NOI1995石子合并&多种石子合并

题目描述

在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 复制
4
4 5 9 4
输出样例#1: 复制
43
54

*****石子合并分为两个梯度的形式
第一种就是一条线那样的石子合并
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int i,j,l,k,n,a[105],f[105][105],s[105];
 7 int main()
 8 {
 9     scanf("%d",&n);
10     s[0] = 0;
11     for(i = 1;i <= n;i++)
12     {
13         scanf("%d",&a[i]);
14         s[i] = s[i - 1] + a[i];
15     }
16     for(l = 2;l <= n;l++)
17     {
18         for(i = 1;i <= n + l - 1;i++)
19         {
20             j = i + l - 1;
21             for(k = i;k <= j - 1;k++)
22             {
23                 if(f[i][j] != 0)
24                 f[i][j] = min(f[i][j],f[i][k] + f[k + 1][j] + s[j] - s[i - 1]);
25                 else
26                 f[i][j] = f[i][k] + f[k + 1][j] + s[j] - s[i - 1];
27             }
28         }
29     }
30     printf("%d",f[1][n]);
31     return 0;
32 }
第二种是围成一个圈那样,和这道题就是这个类型
O(N^3)有两种算法
第一种就是

 

这种啊博主也没怎么看懂,等着2020年6月9号看吧吼吼
下面这种博主还是会滴
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int i,j,m,n,l,k,da = 0,an = 0,a[205],f[205][205],s[205],p[205][205];
 7 int main()
 8 {
 9     scanf("%d",&n);
10     s[0] = 0;
11     for(i = 1;i <= n;i++)
12     {
13         scanf("%d",&a[i]);
14         a[i + n] = a[i];
15     }
16     for(i = 1;i <= 2 * n;i++)
17     {
18         s[i] = s[i - 1] + a[i];
19     }
20     for(l = 2;l <= n;l++)
21     {
22         for(i = 1;i <= n * 2 - l;i++)
23         {
24             j = i + l - 1;
25             for(k = i;k <= j - 1;k++)
26             {
27                 if(f[i][j] != 0)
28                 f[i][j] = min(f[i][j],f[i][k] + f[k + 1][j] + s[j] - s[i - 1]);
29                 else
30                 f[i][j] = f[i][k] + f[k + 1][j] + s[j] - s[i - 1];
31                 p[i][j] = max(p[i][j],p[i][k] + p[k + 1][j] + s[j] - s[i - 1]);
32             }     
33         }
34     }
35     for(i = 1;i <= n;i++)
36     {
37         if(da != 0)
38         da = min(da,f[i][i + n - 1]);
39         else
40         da = f[i][i + n - 1];
41         an = max(an,p[i][i + n - 1]);
42     }
43     printf("%d
%d",da,an);
44     return 0;
45 }


 
 
 
原文地址:https://www.cnblogs.com/rax-/p/9805089.html