题目描述 Description
有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。
输入描述 Input Description
第一行一个整数n(n<=100)
第二行n个整数w1,w2...wn (wi <= 100)
输出描述 Output Description
一个整数表示最小合并代价
样例输入 Sample Input
4
4 1 1 4
样例输出 Sample Output
18
数据范围及提示 Data Size & Hint
思路:
区间dp(其实就是暴力枚举(毕竟这题数据太水(没办法(>.<))));
来,上代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,dp[101][101][101],sum[101]; int main() { scanf("%d",&n); memset(dp,127/3,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d",&dp[0][i][i]); sum[i]=sum[i-1]+dp[0][i][i]; dp[0][i][i]=0; } for(int i=1;i<n;i++){for(int j=1;j<=n;j++) dp[i][j][j]=dp[0][j][j];} for(int i=1;i<n;i++) { for(int j=1;j<=n;j++) { for(int r=j;r<=n;r++) { dp[i][j][r]=min(dp[i][j][r],dp[i-1][j][r]); for(int v=j;v<r;v++) { dp[i][j][r]=min(dp[i][j][r],dp[i-1][j][v]+dp[i-1][v+1][r]+sum[r]-sum[j-1]); } } } } printf("%d ",dp[n-1][1][n]); return 0; }