1. 程式人生 > >NYOJ題目737石子合併(一)(區間dp)

NYOJ題目737石子合併(一)(區間dp)

石子合併(一)

時間限制:1000 ms  |  記憶體限制:65535 KB 難度:3
描述
    有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子併成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過N-1次合併後成為一堆。求出總的代價最小值。
輸入
有多組測試資料,輸入到檔案結束。
每組測試資料第一行有一個整數n,表示有n堆石子。
接下來的一行有n(0< n <200)個數,分別表示這n堆石子的數目,用空格隔開
輸出
輸出總代價的最小值,佔單獨的一行
樣例輸入
3
1 2 3
7
13 7 8 16 21 4 18
樣例輸出
9
239
來源
經典問題
上傳者
TC_胡仁東 ac程式碼
#include<string.h>
#include<stdio.h>
#define INF 0xfffffff
int m[205][205];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int a[1000],i,j,k,r,t,sum[1000];
		sum[0]=0;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			sum[i]=sum[i-1]+a[i];
		}
		memset(m,0,sizeof(m));
		for(r=2;r<=n;r++)
		{
			for(i=1;i+r-1<=n;i++)
			{
				j=i+r-1;
				m[i][j]=INF;
				for(k=i;k<j;k++)
				{
					t=m[i][k]+m[k+1][j]+sum[j]-sum[i-1];
					if(t<m[i][j])
						m[i][j]=t;
				}
			}
		}
		printf("%d\n",m[1][n]);
	}
}