UVa 11584 - Partitioning by Palindromes(简单DP)

来源:互联网 发布:剑三抓马坐标数据下载 编辑:程序博客网 时间:2024/05/01 14:59

Partitioning by Palindromes

Time Limit:1000MS Memory Limit:Unknown 64bit IO Format:%lld & %llu

[Submit]  [Go Back]  [Status]  

Description

Download as PDF

Problem H: Partitioning by Palindromes

Can you read upside-down?

We say a sequence of characters is a palindrome if it is the same written forwards and backwards. For example, 'racecar' is a palindrome, but 'fastcar' is not.

A partition of a sequence of characters is a list of one or more disjoint non-empty groups of consecutive characters whose concatenation yields the initial sequence. For example, ('race', 'car') is a partition of 'racecar' into two groups.

Given a sequence of characters, we can always create a partition of these characters such that each group in the partition is a palindrome! Given this observation it is natural to ask: what is the minimum number of groups needed for a given string such that every group is a palindrome?

For example:

  • 'racecar' is already a palindrome, therefore it can be partitioned into one group.
  • 'fastcar' does not contain any non-trivial palindromes, so it must be partitioned as ('f', 'a', 's', 't', 'c', 'a', 'r').
  • 'aaadbccb' can be partitioned as ('aaa', 'd', 'bccb').

Input begins with the number n of test cases. Each test case consists of a single line of between 1 and 1000 lowercase letters, with no whitespace within.

For each test case, output a line containing the minimum number of groups required to partition the input into groups of palindromes.

Sample Input

3racecarfastcaraaadbccb

Sample Output

173

Kevin Waugh


题意:

由小写字母组成的字符串,求他最少需要划分为多少个串,才能满足所有划分的字串都是回文串。


思路:

简单DP

刚开始我是 dp[i][j] 表示i-j至少需要划分数量,结果超时了 复杂度O(n^3)

dp[i] 表示以i为结尾的字符串的最少划分数量 dp[i] = min(dp[j]+1) j<i && s[j+1...i]是回文串


#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;//#define WIN#ifdef WINtypedef __int64 LL;#define iform "%I64d"#define oform "%I64d\n"#define oform1 "%I64d"#elsetypedef long long LL;#define iform "%lld"#define oform "%lld\n"#define oform1 "%lld"#endif#define S64I(a) scanf(iform, &(a))#define P64I(a) printf(oform, (a))#define P64I1(a) printf(oform1, (a))#define REP(i, n) for(int (i)=0; (i)<n; (i)++)#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)const int INF = 0x3f3f3f3f;const double eps = 10e-9;const double PI = (4.0*atan(1.0));const int maxn = 1000 + 20;char s[maxn];int dp[maxn];int ish[maxn][maxn];int n;bool init() {    for(int len=1; len<=n; len++) {        for(int i=0; i<n; i++) {            int j = i + len - 1;            if(j >= n) break;            if(s[i] == s[j] && (i+1==j || ish[i+1][j-1]))                ish[i][j] = 1;            else                ish[i][j] = 0;        }    }}int main() {    int T;    scanf("%d", &T);    while(T--) {        scanf("%s", s);        n = strlen(s);        memset(ish, -1, sizeof(ish));        init();        dp[0] = 1;        for(int i=1; i<n; i++) {            dp[i] = dp[i-1] + 1;            for(int j=0; j<i; j++) if(ish[j][i]) {                int t = 1;                if(j > 0) t += dp[j-1];                dp[i] = min(dp[i], t);            }        }        printf("%d\n", dp[n-1]);    }    return 0;}



0 0
原创粉丝点击