来源:http://codeforces.com/problemset/problem/137/D
题意:给你一个字符串,求最多分成k个回文所添加的最少字母数。
#include <iostream>
#include <algorithm>
#include <map>
#include <cstdio>
#include <set>
#include <cstring>
#include <string>
#define INF 100000000
using namespace std;
string str;
int n ,k;
int p[505][505],dp[505][505];
int a[505],pre[505][505];
int main()
{
cin>>str>>k;
n=str.size();
for(int i=n-1;i >= 0;i--)
{
for(int j=i;j<n;j++)
{
if(i==j)
{
p[i][j]=0;
}
else if(j-i==1)
{
p[i][j]=(str[i]==str[j])?0:1;
}
else
{
int c=(str[i]==str[j])?0:1;
p[i][j]=p[i+1][j-1]+c;
}
}
}
for(int i=0;i<n;i++)
{
dp[i][1]=p[0][i];
pre[i][1]=-1;
for(int j=2;j<=k;j++)
{
int temp=INF;
pre[i][j]=-1;
for(int u=0;u<i;u++)
{
if(temp>dp[u][j-1]+p[u +1][i])
{
temp=dp[u][j-1]+p[u+1][i];
pre[i][j]=u;
}
}
dp[i][j]=temp;
}
}
int cnt , res=INF;
for(int i=1;i<=k;i++)
{
if(res>dp[n-1][i])
{
res=dp[n-1][i];
cnt=i;
}
}
cout<<res<<endl;
int u=n-1,x=cnt;
while(u!=-1)
{
a[x]=u;
//cout<<a[x]<<endl;
u=pre[u][x--];
}
a[0]=-1;
string s;
for(int i=1;i<=cnt;i++)
{
int left=a[i-1]+1;
int right=a[i];
for(int k=0;k<=right-left;k++)
{
if(str[left+k]!=str[right-k])
{
str[left+k]=str[right-k];
}
s+=str[left+k];
//cout<<s<<endl;
}
if(i!=cnt)
s+="+";
}
cout<<s<<endl;
return 0;
}