1. 程式人生 > >【NOIP2006】能量項鏈

【NOIP2006】能量項鏈

cst 裏的 col noip splay closed 成了 n) style

本題在洛谷上的鏈接:https://www.luogu.org/problemnew/show/P1063


額,和石子合並好像的QwQ。

的確和石子合並很像,我們定義狀態dp[i][j]表示從第i顆到第j顆所能釋放的最大能量,顯然,dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+head[i]*tail[k]*tail[j]),可以認為是先將i到k合並成一顆珠子,再將k+1到j合並成一顆珠子,最後將兩顆珠子合並(石子合並也可以這樣想)。和石子合並一樣,這裏的珠子成了環,因此可以開兩倍的數組,來處理。註意,這樣在枚舉左端點時i,是從1到2*n-i(2*n用不到)。

技術分享圖片
 1 #include<cstdio>
 2 inline int max(int a,int b) {return a>b?a:b;}
 3 const int maxn=105;
 4 int n,head[2*maxn],tail[2*maxn],dp[2*maxn][2*maxn],ans;
 5 int main() {
 6     scanf("%d",&n);
 7     for(int i=1;i<=n;++i) {scanf("%d",&head[i]);head[n+i]=head[i];}
 8     for
(int i=1;i<=n;++i) tail[i]=i==n?head[1]:head[i+1],tail[n+i]=tail[i]; 9 for(int l=2;l<=n;++l) 10 for(int i=1;i<=2*n-l;++i) { 11 int j=i+l-1; 12 for(int k=i;k<j;++k) 13 dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+head[i]*tail[k]*tail[j]);
14 if(l==n) ans=max(ans,dp[i][j]); 15 } 16 printf("%d",ans); 17 return 0; 18 }
AC代碼

【NOIP2006】能量項鏈