51nod 1021 石子归并 - 区间dp(经典)
题目地址:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1021
经典区间dp,dp[i][j] 表示将从 i 到 j 堆石子合并最小代价,长度为 j-i+1,可看做之前已经合并的 i 到 k 和 k 到 j 两堆石子合并,代价是 i 到 j 的石子数量;
#include<iostream> #include<cstring> #include<algorithm> using namespace std; #define INF 1e9 #define min(a,b) a>b?b:a const int N = 100+5; int n, sum[N], dp[N][N]; int main() { ios::sync_with_stdio(false); while(cin>>n) { memset(sum, 0, sizeof(sum)); memset(dp, 0, sizeof(dp)); for(int a,i=1; i<=n; i++) { cin>>a; sum[i] = sum[i-1]+a; } for(int len=2; len<=n; len++) { for(int i=1; i+len-1<=n; i++) { int e = i+len-1; dp[i][e] = INF; for(int k=i; k<e; k++) { dp[i][e] = min(dp[i][e], dp[i][k]+dp[k+1][e]+sum[e]-sum[i-1]); } } } cout<<dp[1][n]<<endl; } return 0; }