【题解】剪纸条(dp)

【题解】剪纸条(dp)

HRBUST - 1828

网上搜不到题解?那我就来写一篇吧哈哈哈

最优化问题先考虑\(dp\),设\(dp(i)\)表示将前\(i\)个字符(包括\(i\))分割成不相交的回文子串的最小数目

直接模拟题意转移即可。初始化写在里面了,\(dp(i)=i\)

\[dp(i)=\min\{i,dp(j-1)\} \]

其中\(S[j\dots i]\)是一个回文串,\(O(n^2)\)预处理回文串即可,注意偶回文串和奇回文串。

刚开始想太多,这道题。以后遇最优化的题一定要花有一定量的时间设计DP,因为DP的操作性强,正确性也比较好验证,即使后面有其他的解法,DP也可以作为对拍的保障。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std; 
const int maxn=1e2+5;
char c[maxn];
int dp[maxn],in[maxn][maxn],n;

int main(){
      c[0]='_';
      while(~scanf("%s",c+1)){
	    n=strlen(c+1);
	    for(register int t=1;t<=n;++t)
		  for(register int i=1;i<=n;++i)
			in[t][i]=0;
	    for(register int t=1;t<=n;++t){
		  register int p=0;
		  while(c[t-p]==c[t+p]) in[t-p][t+p]=1,++p;
		  p=0;
		  while(c[t-p]==c[t+1+p]) in[t-p][t+1+p]=1,++p;
		  dp[t]=t;
	    }
	    for(register int t=1;t<=n;++t)
		  for(register int i=1;i<=t;++i)
			if(in[i][t])
			      dp[t]=min(dp[t],dp[i-1]+1);
	    printf("%d\n",dp[n]-1);
      }
      return 0;
}


posted @ 2019-08-26 20:00  谁是鸽王  阅读(219)  评论(0编辑  收藏  举报