当前位置:   article > 正文

P8709 [蓝桥杯 2020 省 A1] 超级胶水(Python)

P8709 [蓝桥杯 2020 省 A1] 超级胶水(Python)

记录蓝桥杯刷题,题目链接:P8709 [蓝桥杯 2020 省 A1] 超级胶水

题目

题目描述:

小明有 n 颗石子,按顺序摆成一排,他准备用胶水将这些石子粘在一起。

每颗石子有自己的重量,如果将两颗石子粘在一起,将合并成一颗新的石子,重量是这两颗石子的重量之和。

为了保证石子粘贴牢固,粘贴两颗石子所需要的胶水与两颗石子的重量乘积成正比,本题不考虑物理单位,认为所需要的胶水在数值上等于两颗石子重量的乘积。

每次合并,小明只能合并位置相邻的两颗石子,并将合并出的新石子放在原来的位置。

现在,小明想用最少的胶水将所有石子粘在一起,请帮助小明计算最少需要多少胶水。

输入格式:

输入的第一行包含一个整数 n,表示初始时的石子数量。

第二行包含 n 个整数w1​,w2​,⋯,wn​ 依次表示每颗石子的重量。

输出格式:

输出一行包含一个整数,表示最少需要的胶水数。

思考(错误)

以下思考内容为错误思路,不要看!

用w[i]表示i号石子重量。

最开始一看,觉得就是动态规划做题,设计两个量heavy与glue, heavy[i][j]表示从i号石子到j号石子总重量,glue[i][j]表示粘贴从i号石子到j号石子所需最少胶水量,那就可以有这样的公式:

 

然后,为了代码方便,可以换一个思路:

我首先找出来粘贴两个石子最少的胶水,然后三个、四个、五个,最后粘完全部石子,那么,首先可以得出:

glue[i][j]=w[i]*w[j]\left ( j=i+1 \right )

假设粘贴k+1个石子,从i号石子到i+k号石子,最后粘贴的位置为j号石子与j+1号石子中间,那么有:

glue[i][i+k]=min(glue[i][j]+glue[j+1][i+k]+heavy[i][j]*heavy[j+1][i+k]),i<=j<i+k

最后就可以通过循环完成了,代码如下:

  1. n=int(input())
  2. w=input().split()
  3. heavy=[]
  4. glue=[]
  5. for i in range(0,n):
  6. w[i]=int(w[i])
  7. for i in range(0,n):
  8. next1=[]
  9. next2=[]
  10. for j in range(0,n):
  11. next1.append(0)
  12. next2.append(0)
  13. heavy.append(next1)
  14. glue.append(next2) #初始化数组
  15. for i in range(0,n):
  16. for j in range(i,n):
  17. for k in range(i,j+1):
  18. heavy[i][j]+=w[k]
  19. for i in range(0,n-1):
  20. glue[i][i+1]=w[i]*w[i+1]
  21. for k in range(2,n):
  22. for i in range(0,n-k): #从glue[0][k]到glue[n-k-1][n-1]
  23. minx=9999999999
  24. for j in range(i,i+k):
  25. need=glue[i][j]+glue[j+1][i+k]+heavy[i][j]*heavy[j+1][i+k]
  26. if need<minx:
  27. minx=need
  28. glue[i][i+k]=minx
  29. print(glue[0][n-1])

自信满满地提交,好,代码超时,内存过大

无可奈何

然后看了一下题解,破防了

正确题解

注意看,这个题目叫注意看()

注意看,假设三个石子重量分别为a,b,c,先粘1、2石子,再粘3号石子,那么总胶水量为

a*b+(a+b)*c=a*b+a*c+b*c

同理,假设4个石子重量分别为a到d,那么胶水总消耗:

a*b+a*c+a*d+b*c+b*d+c*d

显然可见,胶水消耗量跟粘贴顺序没关系,随便咋粘都可以······

那我那个动态规划算啥啊?!小丑竟是我自己

行吧,最后代码展示如下:

  1. n=int(input())
  2. w=input().split()
  3. sum=0
  4. for i in range(0,n):
  5. w[i]=int(w[i])
  6. heavy=w[0]
  7. for i in range(1,n):
  8. sum += heavy * w[i]
  9. heavy+=w[i]
  10. print(sum)

好好好,时间复杂度只要O(n)就好了是吧······

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/48196
推荐阅读
相关标签
  

闽ICP备14008679号