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的时候要特判

下附代码:

 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 }
View Code

 

posted @ 2021-03-14 15:37  我是菜狗QAQ  阅读(129)  评论(0编辑  收藏  举报