1. 程式人生 > >石子合併 四邊形優化

石子合併 四邊形優化

Description
  在一個操場上擺放著一排N堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。
  試設計一個演算法,計算出將N堆石子合併成一堆的最小得分。

Input
  第一行是一個數N。
  以下N行每行一個數A,表示石子數目。

Output
  共一個數,即N堆石子合併成一堆的最小得分。

Sample Input
4
1
1
1
1

Sample Output
8

#include<stdio.h>
#include<algorithm>
using namespace std; const int inf=2100000000; const int maxn=1001; int temp,n,best,sum[maxn],s[maxn][maxn],dp[maxn][maxn]; inline const int read(){ register int f=1,x=0; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3
)+(x<<1)+ch-'0';ch=getchar();} return x*f; } void reset(){ temp=inf; } int main(){ n=read(); for(register int i=1;i<=n;i++){ sum[i]=read(); sum[i]+=sum[i-1]; s[i][i]=i; } for(register int i=n;i>=1;i--) for(register int j=i+1;j<=n;j++){ reset(); for
(register int k=s[i][j-1];k<=s[i+1][j];k++) if(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]<temp){ temp=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]; best=k; } s[i][j]=best; dp[i][j]=temp; } printf("%d",dp[1][n]); }