洛谷P1063 能量項鏈 區間動歸
阿新 • • 發佈:2017-08-31
題目 color 不同 style code 斷點 cout ron names
題目描述
在Mars星球上,每個Mars人都隨身佩帶著一串能量項鏈。在項鏈上有N顆能量珠。能量珠是一顆有頭標記與尾標記的珠子,這些標記對應著某個正整數。並且,對於相鄰的兩顆珠子,前一顆珠子的尾標記一定等於後一顆珠子的頭標記。因為只有這樣,通過吸盤(吸盤是Mars人吸收能量的一種器官)的作用,這兩顆珠子才能聚合成一顆珠子,同時釋放出可以被吸盤吸收的能量。如果前一顆能量珠的頭標記為m,尾標記為r,後一顆能量珠的頭標記為r,尾標記為n,則聚合後釋放的能量為m*r*n(Mars單位),新產生的珠子的頭標記為m,尾標記為n。 需要時,Mars人就用吸盤夾住相鄰的兩顆珠子,通過聚合得到能量,直到項鏈上只剩下一顆珠子為止。顯然,不同的聚合順序得到的總能量是不同的,請你設計一個聚合順序,使一串項鏈釋放出的總能量最大。
思路: 該題與石子合並相似。
轉移方程: f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+c[l]*c[k+1]*c[r+1]);
#include<iostream> #include<cstdio> using namespace std; int n; int a[500]; int f[500][500]; int main() { cin >> n; for (int i=1;i<=n;i++) { cin >> a[i]; a[i+n]=a[i]; }for (int i=2;i<2*n;i++)//枚舉區間大小 for (int l=1;l+i-1<2*n;l++)//枚舉左端點 { int r=l+i-1;//右端點 for (int k=l;k<r;k++)//枚舉區間斷點 f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]); } int ans=0; for (int i=1;i<=n;i++) ans=max(ans,f[i][i+n-1]); cout << ans << endl; return 0; }
洛谷P1063 能量項鏈 區間動歸