51nod 1021 石子归并

Posted 小小超plus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1021 石子归并相关的知识,希望对你有一定的参考价值。

N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。
 
例如: 1 2 3 4,有不少合并方法
1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)
1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)
1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)
 
括号里面为总代价可以看出,第一种方法的代价最低,现在给出n堆石子的数量,计算最小合并代价。
 
Input
第1行:N(2 <= N <= 100)
第2 - N + 1:N堆石子的数量(1 <= A[i] <= 10000)
Output
输出最小合并代价
Input示例
4
1
2
3
4
Output示例
19
dp模板题
技术分享图片
 1 #include <iostream>
 2 using namespace std;
 3 #include<string.h>
 4 #include<set>
 5 #include<stdio.h>
 6 #include<math.h>
 7 #include<queue>
 8 #include<map>
 9 #include<algorithm>
10 #include<cstdio>
11 #include<cmath>
12 #include<cstring>
13 #include <cstdio>
14 #include <cstdlib>
15 #include<stack>
16 #include<vector>
17 int dp[110][110];
18 int dp1[110][110];
19 int a[110];
20 int main()
21 {
22     int n;
23     cin>>n;
24     for(int i=1;i<=n;i++)
25         cin>>a[i];
26     memset(dp,0,sizeof(dp));
27     memset(dp1,0,sizeof(dp1));
28     for(int i=1;i<=n;i++)
29     {
30         for(int j=i;j<=n;j++)
31         {
32             dp[i][j]=dp[i][j-1]+a[j];
33             if(i==j)
34                 continue;
35                 dp1[i][j]=1e8;
36         }
37     }
38     for(int i=1;i<=n;i++)
39     {
40         for(int j=i-1;j>0;j--)
41         {
42             if(i-j==1)
43             {
44                 dp1[j][i]=dp[j][i];
45                 continue;
46             }
47 
48             for(int k=j;k<=i;k++)
49                 {
50 
51                     dp1[j][i]=min(dp1[j][i],dp1[j][k]+dp1[k+1][i]+dp[j][i]);
52                 }
53                // cout<<j<<"_"<<i<<"_"<<dp1[j][i]<<endl;
54         }
55     }
56     cout<<dp1[1][n]<<endl;
57 }
View Code

 


以上是关于51nod 1021 石子归并的主要内容,如果未能解决你的问题,请参考以下文章

51Nod 1021 石子归并

51nod 1021 石头归并

石子归并 51Nod - 1021

51nod 1021 石子归并(dp)

石子归并 51Nod - 1021

51nod 1021 石子归并