1. 程式人生 > >-----區間DP 石子的合併

-----區間DP 石子的合併

石子合併

時間限制:1000 ms | 記憶體限制:65535 KB
難度:3
描述
有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子併成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過N-1次合併後成為一堆。求出總的代價最小值。
輸入
有多組測試資料,輸入到檔案結束。
每組測試資料第一行有一個整數n,表示有n堆石子。
接下來的一行有n(0< n <200)個數,分別表示這n堆石子的數目,用空格隔開
輸出
輸出總代價的最小值,佔單獨的一行

#include<iostream>
#include<stdio.h>
#include<string.h> #include<algorithm> using namespace std; #define INF 0x3fffffff const int N = 205; int a[N], sum[N], dp[N][N]; int main() { int n, i, j; while(~scanf("%d",&n) && n) { sum[0]=0; for(int i=1;i<=n;i++) { cin>>a[i]; dp[i][i]=0
; sum[i]=sum[i-1]+a[i]; } for(int len=2;len<=n;len++)///列舉每一種長度 { for(int i=1;i<=n;i++)///列舉所有起點 { int j=i+len-1;///起點為i的時候,長度為len的時候,終點為j if(j>n) continue; dp[i][j]=INF;///把起點為i,終點為j的dp值初始化為一個很大的值
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]);///取最小的方案的時候i到j的最小dp值 } } printf("%d\n",dp[1][n]); } }