51nod1154(dp)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1154

题意:中文题目诶~

思路:字符串长度不大于5e3,O(n^2)时间复杂度就足够了.那么可以用dp解,dp[i]存储以i为尾字符的子串最少能分成几个回文子串;

枚举以i为中心的字串,那么动态转移方程为:

dp[k] = min(dp[k], dp[j-1]+1)

注意:串长为奇数和偶数的情况;

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int MAXN = 5e3+10;
 7 int dp[MAXN];//dp[i]存储以i结尾的字符串最少分成几个回文串
 8 char s[MAXN];
 9 
10 int main(void){
11     int i;
12     scanf("%s", s+1);
13     for(i=1; s[i]!=''; i++) dp[i] = i;
14     for(i=1; s[i]!=''; i++){//枚举以i为中心的字串
15         for(int j=i-1,k=i+1; j>0&&s[k]!=''; j--,k++){//长度为奇数
16             if(s[j] == s[k]) dp[k] = min(dp[k], dp[j-1]+1);
17             else break;
18         }
19         for(int j=i,k=i+1; j>0&&s[k]!=''; j--,k++){//长度为偶数
20             if(s[j] == s[k]) dp[k] = min(dp[k], dp[j-1]+1);
21             else break;
22         }
23         dp[i] = min(dp[i], dp[i-1]+1);
24     }
25     printf("%d
", dp[i-1]);
26     return 0;
27 }
View Code
原文地址:https://www.cnblogs.com/geloutingyu/p/6900940.html