Codevs3002 stones merge 3, codevs3002 stones merge
DescriptionDescription
There are n piles of stones in a column, each pile of stones has a weight w [I], each merge can combine adjacent two piles of stones, the cost of one merge is the weight of two piles of stones and w [I] + w [I + 1]. Ask how to arrange the merge sequence to minimize the total merge cost.
Input description
Input Description
The first line is an integer n (n <= 3000)
N integers w1, w2. .. wn (wi <= 3000) in the second row)
Output description
Output Description
An integer indicates the minimum merge cost.
Sample Input
Sample Input
4
4 1 1 4
Sample output
Sample Output
18
Data range and prompt
Data Size & Hint
The data range is extended compared to the "Stone merge"
Nothing to say,
Is the Quadrilateral inequality optimization.
Prove that neither will I
Drop a blog Link
http://blog.csdn.net/noiau/article/details/72514812
#include<cstdio>#include<cstring>const int MAXN=1e5+10,INF=1e8+10;using namespace std;inline char nc(){ static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin)),p1==p2?EOF:*p1++;}inline int read(){ char c=nc();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();} return x*f;}int dp[3001][3001],sum[MAXN],s[3001][3001];int main(){ #ifdef WIN32 freopen("a.in","r",stdin); #else #endif int N=read(); for(int i=1;i<=N;i++) sum[i]=read(),sum[i]+=sum[i-1],s[i][i]=i; for(int i=N;i>=1;i--) { for(int j=i+1;j<=N;j++) { int mn=INF,mnpos=0; for(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] < mn) { mn=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]; mnpos=k; } } dp[i][j]=mn; s[i][j]=mnpos; } } printf("%d",dp[1][N]); return 0;}