能量项链

原题链接:https://www.luogu.org/problem/show?pid=1063

区间DP题,即把整个问题划分成若干个小区间求解。

这个题细节太多了。。。

最后犯了一个傻逼性错误,数组开小了,死活过不了最后两个点

现在洛谷关站维护中,所以这题我在codevs上跑的。

思路是用f[i][j]表示这条项链上的珠子从i号位合到j号位的最大价值。状态转移方程为f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i]*a[k+1]*a[j+1])。

不过题意说到数据是一个环,这里有两种处理方式。

一种是绝大多数题解里用的化环为链的方法将它变成链状,还有的题解是计算时取模,把这个数据就当成环来看待。

我写的也是化环为链,即在记录a数组的时候把数组开二倍大,i+n处也存储i位置的值,这样就可以模拟出中间的接口。

首先有一个i枚举到2n,枚举的是区间大小,然后有一个l枚举的是左端点,其应该满足l+i-1<2*N,也就是不让右端点越界 。

然后设一个变量r为l+i-1,这个代表的是右端点,然后有一个k从l枚举到r,枚举的是所谓断点。断点实际上就是我们要试图合并的位置。

进行转移,然后枚举1到n处理ans为max(f[i][i+n-1]),最后输出ans就好。

参考代码:

 1 #include <iostream>
 2 #define maxn 300
 3 using namespace std;
 4 int f[maxn][maxn];
 5 int a[maxn];
 6 int n,ans;
 7 
 8 int main(){
 9     cin >> n;
10     for (int i=1;i<=n;i++){
11         cin >> a[i];
12         a[i+n] = a[i];
13     }
14     for (int i=2;i<=2*n;i++) 
15         for (int l=1;l+i-1<=2*n;l++){ 
16           int r=l+i-1;
17           for (int k=l;k<=r;k++)
18               f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]);
19       }
20       
21     for (int i=1;i<=n;i++)
22         ans = max(ans,f[i][i+n-1]);
23     cout << ans << endl;
24     return 0;        
25 }

 

posted @ 2017-09-21 23:50  ShawnZhou_Aether  阅读(147)  评论(0编辑  收藏  举报