The 15-th BIT Campus Programming Contest - Onsite Round C Simple AniPop
区间DP,训练的时候死活没搞清楚某一段区间的代价。
dp[l][r]表示消除[l,r]区间的最大得分,那么得分就是最后一个消除的点k*(l-1)*(r+1)。
所以dp[l][r]=max(dp[l][r],dp[l][k-1]+dp[k+1][r]+a[k]*a[l-1]*a[r+1]);
注意最后长度为n的时候只加a[k],a[0]和a[2*n+1]的位置要赋值否则边界得分取不对。
最后n=1的时候要特判
下附代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 ll a[1005],dp[1005][1005]; 5 int main(){ 6 int n; 7 scanf("%d",&n); 8 for (int i=1; i<=n; i++){ 9 scanf("%lld",&a[i]); 10 a[i+n]=a[i]; 11 } 12 if (n==1) { 13 printf("%lld",a[1]); 14 return 0; 15 } 16 a[0]=a[n]; 17 a[2*n+1]=a[1]; 18 for (int i=1; i<=2*n; i++){ 19 dp[i][i]=a[i-1]*a[i]*a[i+1]; 20 } 21 for (int len=2; len<=n; len++){ 22 for (int l=1; l+len-1<=2*n; l++){ 23 int r=l+len-1; 24 for (int k=l; k<=r; k++){ 25 if (len<n) dp[l][r]=max(dp[l][r],dp[l][k-1]+dp[k+1][r]+a[l-1]*a[k]*a[r+1]); 26 else dp[l][r]=max(dp[l][r],dp[l][k-1]+dp[k+1][r]+a[k]); 27 } 28 } 29 } 30 ll res=0; 31 for (int i=1; i<=n; i++){ 32 res=max(res,dp[i][i+n-1]); 33 } 34 printf("%lld",res); 35 }