題目地址:http://zsyz.openjudge.cn/dp/23/
/*Author:Bob Lee2012.9.20=================================================這是一道中文的題目,題意我就不用解釋了這是一道區間DP我們用f[i][j]表示由i到j的最大能量值那麼它的子問題就是將i到j分成兩段然後相乘的最大值則可以匯出狀態轉移方程f[i][j]= max(f[i][k]+f[k+1][j]+data[i]*data[k+1]*data[j+1])(1<=i<=k<j<=2n-1)其中data[i]表示第i個的頭,i+1才是尾還有一個問題,那就是這個項鏈是一個環所以頭不一定是1那麼我們就在1~n再加一個這樣我們只需要枚舉f[i][n+i-1] (1<=i<=n)求得其最大值*/#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;#define MAXN 105#define INF 1<<30int f[2*MAXN][2*MAXN];int data[2*MAXN];int n;void update(int &x,int y){ if(y>x) x=y;}int main(){ //while(scanf("%d",&n) != EOF) scanf("%d",&n); { int i,j; for(i=1;i<=n;i++) { scanf("%d",&data[i]); data[i+n] = data[i]; } for(i=1;i<=2*n;i++) { for(j=1;j<=2*n;j++) { if(i==j) f[i][j] = 0; else f[i][j] = 0; } } int len; for(len=1;len<n;len++) { for(i=1;i<=2*n-len;i++) { j=i+len; int k; for(k=i;k<j;k++) { update(f[i][j],f[i][k]+f[k+1][j]+data[i]*data[k+1]*data[j+1]); } } } int ans = -INF; for(i=1;i<=n;i++) { update(ans,f[i][n+i-1]); //cout<<f[i][n+i-1]<<endl; } printf("%d\n",ans); } return 0;}