-----區間DP 石子的合併
阿新 • • 發佈:2019-02-03
石子合併
時間限制: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]);
}
}