CodeForces 73 C.LionAge II(dp)

Description

给出一个字符串 s ,可以修改其中不超过 k 个字符,给出 n 对相邻字符的价值,问修改后字符串的最大价值

Input

第一行一个字符串 s 和一个整数 k ,之后输入一整数 n ,最后 n 行每行输入两个小写字母 x , y 和一个整数 c 表示如果 x 后是 y 则多出 c 的价值

( 1 | s | 100 , 0 k 100 , 0 n 676 , 1000 c 1000 )

Output

输出修改后字符串的最大价值

Sample Input

winner 4
4
s e 7
o s 8
l o 13
o o 8

Sample Output

36

Solution

d p [ i ] [ j ] [ x ] 表示前 i 个字符修改 j 次后以第 x 个小写字母结尾的最大价值,枚举第 i + 1 个字符判断是否会有多的价值以及是否需要多修改一个字符进行转移即可,答案即为 m a x ( d p [ n ] [ j ] [ x ] , 0 j k , 0 x < 26 )

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=105;
int k,dp[maxn][maxn][26],n,cost[26][26];
char s[maxn];
int main()
{
    scanf("%s%d%d",s+1,&k,&n);
    while(n--)
    {
        char a[3],b[3];
        int c;
        scanf("%s %s %d",a,b,&c);
        cost[a[0]-'a'][b[0]-'a']=c;
    }
    n=strlen(s+1);
    for(int i=1;i<=n;i++)
        for(int j=0;j<=k;j++)
            for(int x=0;x<26;x++)
                dp[i][j][x]=-INF;
    dp[1][0][s[1]-'a']=0;
    for(int i=0;i<26;i++)
        if(i+'a'!=s[1])dp[1][1][i]=0;
    for(int i=1;i<n;i++)
        for(int j=0;j<=k;j++)
            for(int x=0;x<26;x++)
                if(dp[i][j][x]!=-INF)
                    for(int y=0;y<26;y++)
                    {
                        if(y+'a'==s[i+1])dp[i+1][j][y]=max(dp[i+1][j][y],dp[i][j][x]+cost[x][y]);
                        else if(j<k)dp[i+1][j+1][y]=max(dp[i+1][j+1][y],dp[i][j][x]+cost[x][y]);
                    }
    int ans=-INF;
    for(int i=0;i<=k;i++)
        for(int j=0;j<26;j++)
            ans=max(ans,dp[n][i][j]);
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/v5zsq/article/details/81042544
73