Description
给出一个字符串 s s ,可以修改其中不超过个字符,给出 n n 对相邻字符的价值,问修改后字符串的最大价值
Input
第一行一个字符串和一个整数 k k ,之后输入一整数,最后 n n 行每行输入两个小写字母和一个整数 c c 表示如果后是 y y 则多出的价值
(1≤|s|≤100,0≤k≤100,0≤n≤676,−1000≤c≤1000) ( 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
dp[i][j][x] d p [ i ] [ j ] [ x ] 表示前 i i 个字符修改次后以第 x x 个小写字母结尾的最大价值,枚举第个字符判断是否会有多的价值以及是否需要多修改一个字符进行转移即可,答案即为 max(dp[n][j][x],0≤j≤k,0≤x<26) 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;
}