标签:子串 LG min int 55 P4170 涂色 断点
解析
题意是求对字符串的最少染色次数,设 f[i][j]
为字符串的子串 s[i]
~ s[j]
的最少染色次数,我们分析一下:
当 i==j
时,子串明显只需要涂色一次,于是 f[i][j]=1
。
当 i!=j
且 s[i]==s[j]
时,可以想到只需要在首次涂色时多涂一格即可,于是 f[i][j]=min(f[i][j-1],f[i+1][j])
。
当 i!=j
且 s[i]!=s[j]
时,我们需要考虑将子串断成两部分来涂色,于是需要枚举子串的断点,设断点为 k
,那么 f[i][j]=min(f[i][j],f[i][k]+f[k+1][j])
。
总结一下就是:
\[\large\begin{equation} f_{i,j}= \begin{cases} 1 & i=j\\ \min(f_{i,j-1},f_{i+1,j}) & i\not=j,s_i=s_j\\ \min(f_{i,j},f_{i,k}+f_{k+1,j}) & i\not=j,s_i\not=s_j \end{cases} \end{equation} \]由于 f[i][j]
的定义,我们可以知道 f[1][n]
即为答案。
代码
#include<bits/stdc++.h>
using namespace std;
char c[55];
int f[55][55];
int main() {
scanf("%s",c+1);
int n=strlen(c+1);
memset(f,0x7F,sizeof(f));
for(int i=1; i<=n; i++) {
f[i][i]=1;
}
for(int i=2; i<=n; i++) {
for(int l=1; l<=n; l++) {
int r=l+i-1;
if(r>n) {
break;
}
if(c[l]==c[r]) {
f[l][r]=min(f[l+1][r],f[l][r-1]);
} else {
for(int k=l; k<r; k++) {
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);
}
}
}
}
printf("%d",f[1][n]);
return 0;
}
参考资料
P4170 涂色 - Loner_Knowledge 的博客 - 洛谷博客
标签:子串,LG,min,int,55,P4170,涂色,断点 来源: https://www.cnblogs.com/Sam2007/p/15027802.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。