当前位置:   article > 正文

动态规划(算法竞赛、蓝桥杯)--区间DP石子合并与环形石子合并、能量项链_蓝桥杯合并石子

蓝桥杯合并石子

1、B站视频链接:E28【模板】区间DP 石子合并_哔哩哔哩_bilibili

题目链接:石子合并(弱化版) - 洛谷

bb86f876332947ec8832480e07dac403.png

070cc8a7a95042f1ae6d2f96ea4d0f35.png

54504247cbe64eb2a2821577900d45e6.png

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=310;
  4. int n,a[N],s[N];
  5. int f[N][N];//f[i][j]表示从i到j合并成一堆的最小代价
  6. int main(){
  7. memset(f,0x3f,sizeof(f));
  8. cin>>n;
  9. //预处理
  10. for(int i=1;i<=n;i++){
  11. cin>>a[i],s[i]=s[i-1]+a[i],f[i][i]=0;
  12. }
  13. //状态计算
  14. for(int len=2;len<=n;len++){//区间长度
  15. for(int i=1,j;(j=i+len-1)<=n;i++){//区间端点
  16. for(int k=i;k<j;k++){//区间分割点
  17. f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
  18. }
  19. }
  20. }
  21. cout<<f[1][n];
  22. return 0;
  23. }

2、B站视频链接:E29 区间DP 环形石子合并_哔哩哔哩_bilibili

题目链接:[NOI1995] 石子合并 - 洛谷

311bfa264c154cda93d940ef0ef1207c.png

91bd7ab928974bdb951aa556cf7c6793.png

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=210;
  4. int n,a[N],s[N];
  5. int f[N][N];//最小值
  6. int g[N][N];//最大值
  7. int main(){
  8. memset(f,0x3f,sizeof f);memset(g,-0x3f,sizeof g);
  9. scanf("%d",&n);
  10. for(int i=1;i<=n;i++){
  11. scanf("%d",&a[i]),a[i+n]=a[i];
  12. }
  13. for(int i=1;i<=2*n;i++){
  14. s[i]=s[i-1]+a[i],g[i][i]=0,f[i][i]=0;
  15. }
  16. int minv=1e9,maxv=-1e9;
  17. for(int len=2;len<=n;len++){//枚举区间长度
  18. for(int i=1,j;(j=i+len-1)<=2*n;i++){//区间端点
  19. for(int k=i;k<j;k++){//区间分割点
  20. f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
  21. g[i][j]=max(g[i][j],g[i][k]+g[k+1][j]+s[j]-s[i-1]);
  22. }
  23. minv=min(minv,f[i][i+n-1]);
  24. maxv=max(maxv,g[i][i+n-1]);
  25. }
  26. }
  27. printf("%d\n%d\n",minv,maxv);
  28. return 0;
  29. }

3、B站视频链接:E30 区间DP 能量项链_哔哩哔哩_bilibili

题目链接:[NOIP2006 提高组] 能量项链 - 洛谷

2a10c6ddda8c407883415a1e8caf4031.png

9248d62fecaa4f2ea4dbe4483b4fa2bf.png

76561a94521345d683349119a8654def.png

00147138249f49df9753306652716e84.png

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=210;
  4. int n,a[N];//a[i]为第i颗珠子的头标记
  5. int f[N][N];//f[i][j] 表示合并[i,j]得到的最大能量
  6. int main(){
  7. cin>>n;
  8. for(int i=1;i<=n;i++)cin>>a[i],a[i+n]=a[i];
  9. for(int len=3;len<=n+1;len++){//区间长度
  10. for(int i=1,j;(j=i+len-1)<=2*n;i++){//区间起点
  11. for(int k=i+1;k<j;k++){//枚举分割点
  12. f[i][j]=max(f[i][j],f[i][k]+f[k][j]+a[i]*a[k]*a[j]);
  13. }
  14. }
  15. }
  16. int res=0;
  17. for(int i=1;i<=n;i++){
  18. res=max(res,f[i][i+n]);
  19. }
  20. cout<<res<<endl;
  21. return 0;
  22. }

 

 

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

闽ICP备14008679号