原题链接:http://codeforces.com/contest/790/problem/C
维护出现了a个K,b个V,c个其他字符的最小花费,数据很小,暴力转移就行。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=75+5;
int dp[MAXN][MAXN][MAXN][3];//0->x 1->v 2->k
int cnt[3];
char sv[MAXN];
int judge(char now)
{
switch(now)
{
case 'K':return 2;break;
case 'V':return 1;break;
default :return 0;break;
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
scanf("%d",&n);
scanf("%s",sv+1);
int len=strlen(sv+1);
memset(dp,0x3f,sizeof(dp));
dp[0][0][0][0]=0;
for(int x=0;x<len;x++)
{
for(int v=0;v<len;v++)
{
for(int k=0;k<len;k++)
{
for(int now=0;now<3;now++)
{
for(int nxt=0;nxt<(now==1?2:3);nxt++)
{
int Cnt;
memset(cnt,0,sizeof(cnt));
switch(nxt)
{
case 0:Cnt=x;break;
case 1:Cnt=v;break;
case 2:Cnt=k;break;
}
int i;
for(i=1;i<=len&&cnt[nxt]<=Cnt;i++)
{
cnt[judge(sv[i])]++;
}
if(cnt[nxt]<=Cnt)
continue;
int cost=max(cnt[0]-x,0)+max(cnt[1]-v,0)+max(cnt[2]-k,0)-1;
switch(nxt)
{
case 0:dp[x+1][v][k][nxt]=min(dp[x+1][v][k][nxt],dp[x][v][k][now]+cost);break;
case 1:dp[x][v+1][k][nxt]=min(dp[x][v+1][k][nxt],dp[x][v][k][now]+cost);break;
case 2:dp[x][v][k+1][nxt]=min(dp[x][v][k+1][nxt],dp[x][v][k][now]+cost);break;
}
}
}
}
}
}
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=len;i++)
{
cnt[judge(sv[i])]++;
}
int ans=min(min(dp[cnt[0]][cnt[1]][cnt[2]][0],dp[cnt[0]][cnt[1]][cnt[2]][1]),dp[cnt[0]][cnt[1]][cnt[2]][2]);
printf("%d\n",ans);
return 0;
}