區間DP入門之 石子歸併問題 NYOJ 737
阿新 • • 發佈:2019-01-29
分析:要求n個石子歸併,我們根據dp的思想劃分成子問題,先求出每兩個合併的最小代價,然後每三個的最小代價,依次知道n個。
定義狀態dp [ i ] [ j ]為從第i個石子到第j個石子的合併最小代價。
那麼 dp [ i ] [ j ] = min(dp [ i ] [ k ] + dp [ k+1 ] [ j ]+sum[j]-sum[i])
那麼我們就可以從小到大依次列舉讓石子合併,直到所有的石子都合併。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int dp[105][105]; int val[105],sum[105]; int main(){ int n; while(~scanf("%d",&n)){ sum[0]=0; for(int i=1;i<=n;i++){ scanf("%d",&val[i]); sum[i]=sum[i-1]+val[i]; } memset(dp,0,sizeof(dp)); for(int len=1;len<=n;len++) { for(int i=1;i+len<=n;i++) { int j=len+i; dp[i][j]=1213233; for(int k=i;k<=j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); } } } printf("%d\n",dp[1][n]); } return 0; }