题意:
给你一串字符串, 用尽量少的涂色次数达到目标。
题解:
该题本质是区间dp,设字符串为s.我们定义dp[i][j]为达到s[i,j]目标最少的涂色次数.
当[i,j]长度为1时,dp[i][j]=1;
当[i,j]长度为2时,dp[i][j]=(s[i]==s[j])?1:2;
当[i,j]长度大于2时:
1.s[i]==s[j],区间端点相同,可以看成是在比该区间小一个单位的基础上顺带涂上的
dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
2.s[i]!=s[j],咱们可以把它分成两半,枚举中间点
dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]);
代码:
#include <bits/stdc++.h> using namespace std; const int maxn=1e3+10; int n,dp[maxn][maxn]; char s[maxn]; int main() { int i,j,k,lenS,len; while(scanf("%s",s+1)!=EOF){ lenS=strlen(s+1); for (len=1;len<=lenS;len++){ for (i=1;i<=lenS;i++){ j=i+len-1; if(j>lenS)break; if(len==1)dp[i][j]=1; else if(len==2)dp[i][j]=(s[i]==s[j])?1:2; else{ if(s[i]==s[j])dp[i][j]=min(dp[i+1][j],dp[i][j-1]); else{ dp[i][j]=j-i+1; for (k=i;k<j;k++)dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]); } } } } printf("%d\n",dp[1][lenS]); } return 0; }