题目链接:http://codeforces.com/problemset/problem/219/C
题意:
给你 $n$ 个方块排成水平一排,每个方块都涂上 $k$ 种颜色中的一种。要求对尽量少的方块进行重新涂色,使得任意两个方块的颜色不同。
题解:
$dp[i][x]$ 表示前 $i$ 个方块,第 $i$ 个方块颜色是 $x$,最少重新涂色多少个方块使得满足要求。
AC代码:
#include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=5e5+10; const int maxk=30; int n,k; char in[maxn],out[maxn]; int dp[maxn][maxk]; int pre[maxn][maxk]; int main() { cin>>n>>k; scanf("%s",in+1); for(int i=1;i<=n;i++) { for(int v=1;v<=k;v++) { dp[i][v]=INF; int flag=(in[i]-'A'+1!=v); for(int u=1;u<=k;u++) { if(u==v) continue; if(dp[i][v]>dp[i-1][u]+flag) { dp[i][v]=dp[i-1][u]+flag; pre[i][v]=u; } } } } int ans=INF, clr; for(int i=1;i<=k;i++) if(ans>dp[n][i]) ans=dp[n][i], clr=i; printf("%d ",ans); for(int i=n;i>=1;i--) out[i]='A'+clr-1, clr=pre[i][clr]; printf("%s ",out+1); }