Educational Codeforces Round 59 (Rated for Div. 2)G. Vasya and Maximum Profit 区间dp
Posted lhclqslove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 59 (Rated for Div. 2)G. Vasya and Maximum Profit 区间dp相关的知识,希望对你有一定的参考价值。
题目链接:G. Vasya and Maximum Profit
题意,给个长度为n的01字符串s,以及长度为n数组a.你每次可以选择任意长度L的连续子串(要求子串每个字符相同)从原串中去掉,并获得a【L】的值。问你可能获得的值最多是多少
题解:
dp[i][j][k]代表区间i,j后面跟k的与s[j]相同的字符。
状态转移
第一种去掉j-1后面的k+1字符dp[l][r][k]=max(dp[l][r][k],dp[l][r-1][0]+a[k+1]);
第二种在i,j-1的区间中找一个与s[j]相同的位置p然后去掉中间的部分[p+1,j-1]
dp[i][j][k]=max(dp[i][j][k],dp[i][p][k+1]+dp[p+1][j-1][0]);
最后答案就是dp[0][n-1][0];
#include<bits/stdc++.h> #define ws wewe #define ll long long using namespace std; const int N=105; ll a[N],dp[N][N][N]; int n; string ss; int main() { scanf("%d",&n); cin>>ss; for(int i=1;i<=n;i++)scanf("%I64d",&a[i]); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { dp[i][i][j]=a[j+1]; } } for(int s=2;s<=n;s++)//枚举区间长度 { for(int l=0;l+s-1<n;l++)//枚举区间左节点 { int r=l+s-1; for(int k=0;k<n;k++)//枚举后面有多少个s[r]相同的字符 { dp[l][r][k]=dp[l][r-1][0]+a[k+1]; for(int j=l;j<r;j++) { if(ss[j]==ss[r]) { dp[l][r][k]=max(dp[l][r][k],dp[l][j][k+1]+dp[j+1][r-1][0]); } } } } } printf("%I64d ",dp[0][n-1][0]); return 0; }
以上是关于Educational Codeforces Round 59 (Rated for Div. 2)G. Vasya and Maximum Profit 区间dp的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33