【基础练习】【区间DP】codevs2102 石子归并2(环形)题解

迈不过友情╰ 2022-08-03 14:50 283阅读 0赞

题目描述 Description

在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入描述 Input Description

数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

输出描述 Output Description

输出共2行,第1行为最小得分,第2行为最大得分.

样例输入 Sample Input

4
4 4 5 9

样例输出 Sample Output

43
54

将环形变成线性,数组开大一倍即可。

ans=min{f[1,n],f[2,n+1],…,f[n,2n-1]}

复杂度O(n^3)

前缀和等与线性一致,只是要注意循环什么的都要开到2*n-1

代码在此

  1. //codevs2102 石子归并2(环形) 区间DP
  2. //copyright by ametake
  3. #include
  4. #include
  5. #include
  6. using namespace std;
  7. const int maxn=200+10;
  8. const int maxint=0x3f3f3f3f;
  9. int s[maxn],f[maxn][maxn],m[maxn][maxn];//m is max
  10. int x,n;
  11. int main()
  12. {
  13. scanf("%d",&n);
  14. for (int i=1;i<=n;i++)
  15. {
  16. scanf("%d",&x);
  17. s[i]=s[i-1]+x;
  18. }
  19. for (int i=n+1;i<=2*n-1;i++)
  20. {
  21. s[i]=s[i-1]+s[i-n]-s[i-n-1];
  22. }
  23. //for (int i=1;i<=2*n-1;i++) printf("%d*\n",s[i]);
  24. //on is right
  25. for (int p=1;p<2*n-1;p++)
  26. {
  27. for (int i=1;i<=2*n-p-1;i++)
  28. {
  29. int j=i+p;
  30. f[i][j]=maxint;
  31. for (int k=i;k
  32. yy) yy=m[i][i+n-1];
  33. }
  34. /*for (int i=1;i<=n;i++)
  35. {
  36. for (int j=1;j<=n;j++)
  37. printf("%d ",f[i][j]);
  38. printf("\n");
  39. }*/
  40. printf("%d\n%d\n",xx,yy);
  41. scanf("%d",&x);
  42. return 0;
  43. }

——今古恨,几千般,只应离合是悲欢

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读

    相关 282 石子合并(区间dp)

    1. 问题描述: 设有 N 堆石子排成一排,其编号为 1,2,3,…,N。每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N 堆石子合并成为一堆。每次只能合并相邻的两

    相关 51nod1021石子归并区间dp)

    题意:N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。