【四边形不等式】noi95- 合并石子

【题目大意】

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

【思路】

设 dp[i][j] 表示第 i 到第 j 堆石子合并的最优值,sum[i][j] 表示第 i 到第 j 堆石子的总数量。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int N=205;
 5 const int INF=0x7fffffff;
 6 int n;
 7 int a[N],sum[N],dp[N][N],s[N][N];
 8 
 9 void f()
10 {    for (int i=1;i<=n;i++) dp[i][i]=0,s[i][i]=i;
14      for (int r=1;r<n;r++)
15      {
16          for (int i=1;i<n;i++)
17         {
18             int j=i+r;
19             if(j>n) break;
20             dp[i][j]=INF;
21             for (int k=s[i][j-1];k<=s[i+1][j];k++)
22             {
23                 if(dp[i][j]>dp[i][k]+dp[k+1][j])
24                 {
25                     dp[i][j]=dp[i][k]+dp[k+1][j];
26                     s[i][j]=k;
27                 }
28             }
29             dp[i][j]+=sum[j]-sum[i-1];
30         }
31     }
32 }
33 
34 int main()
35 {
36      while(~scanf("%d",&n))
37      {
38          sum[0]=0;
39         for (int i=1;i<=n;i++)
40         {
41             scanf("%d",&a[i]);
42             sum[i]=sum[i-1]+a[i];
43         }
44         f();
45         printf("%d
",dp[1][n]);
46      }
47      return 0;
48 
49 }
原文地址:https://www.cnblogs.com/iiyiyi/p/5904205.html