和上一题 “照明系统设计”类似,我们可以逐步递推出最优解,d[i] 表示1~i个字符的最优解,那么d[i] = min(d[i],d[j] + 1)|当s[j+1~i]为回文串时。
大家可以自行打印d这个数组,来体会一下状态的转移情况。
代码如下:
#include<bits/stdc++.h> using namespace std; const int maxn = 1000 + 10; const int INF = 2000000000; int T,n,cnt[maxn][maxn],d[maxn]; char s[maxn]; int main() { scanf("%d",&T); while(T--) { scanf("%s",s+1); n = strlen(s+1); s[0] = '?'; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) { // 预处理,cnt[i][j] = 1 表示[i,j]区间为回文串 int L=i, R=i; cnt[i][i] = 1; while(true) { if(s[L] == s[R]) { cnt[L][R] = 1; L--; R++; } else if(s[L]!=s[R]) { L++; R--; break; } if(L<1 || R>n) { L++; R--; break; } } if(s[i]==s[i+1]) { L = i; R = i+1; cnt[i][i+1] = 1; while(true) { if(s[L] == s[R]) { cnt[L][R] = 1; L--; R++; } else if(s[L]!=s[R]) { L++; R--; break; } if(L<1 || R>n) { L++; R--; break; } } } if(s[i]==s[i-1]) { L = i-1; R = i; cnt[i-1][i] = 1; while(true) { if(s[L] == s[R]) { cnt[L][R] = 1; L--; R++; } else if(s[L]!=s[R]) { L++; R--; break; } if(L<1 || R>n) { L++; R--; break; } } } } //dp for(int i=1;i<=n;i++) { d[i] = INF; for(int j=0;j<i;j++) { if(cnt[j+1][i]) { d[i] = min(d[i],d[j] + 1); } } } printf("%d\n",d[n]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
11584 - Partitioning by Palindromes(DP)
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/46842467