HDU 4628 Pieces

Pieces

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 743    Accepted Submission(s): 441

Problem Description
You heart broke into pieces.My string broke into pieces.But you will recover one day,and my string will never go back. Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need? For example, we can erase abcba from axbyczbea and get xyze in one step.
 
Input
The first line contains integer T,denote the number of the test cases. Then T lines follows,each line contains the string s (1<= length of s <= 16). T<=10.
 
Output
For each test cases,print the answer in a line.
 
Sample Input
2
aa
abb
 
Sample Output
1
2
 
Source
 

 多校第三场1008,比赛时想了一个贪心的算法,但正确性无法保证,而且难写,当时代码写了200多行,交了2次都是Wrong Answer,最终放弃了这个题。

比赛结束后看别人的赵玉博客才知道这是一道状态压缩DP,自己以前没写过这种DP,于是正好学习一下。

用状态压缩把所有的状态枚举出来,用数组记录所表示状态所有字符被删除干净的最少次数。

状态:dp[x]表示在状态x下把所有字符删除的最少次数。

状态压缩:dp[x] = min{dp[x], dp[k]}(k是x的子集)

这样的dp的边界不再是dp[0]或dp[n]了。而是对每个状态都要设定原始值,如果某个状态是完全回文的,则dp[x] = 1,否则,dp[x] 就是一个最大值(目前子串的长度)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 
 6 using namespace std;
 7 
 8 int len;
 9 long all;
10 char s[20];
11 long dp[70000];
12 
13 int initial(int x)
14 {
15     vector<int> q;
16 
17     for(int i=0;i<=len;i++)
18         if(x&(1<<i))
19             q.push_back(i);
20 
21     int k=q.size()-1;
22 
23     for(int i=0;i<=k/2;i++)
24         if(s[q[i]]!=s[q[k-i]])
25             return q.size();
26 
27     return 1;
28 }
29 
30 int main()
31 {
32     int t;
33 
34     scanf("%d",&t);
35     getchar();
36 
37     while(t--)
38     {
39         gets(s);
40 
41         len=strlen(s);
42         all=(1<<len)-1;
43 
44         for(int i=1;i<=all;i++)
45         {
46             dp[i]=initial(i);
47             for(int j=i;j>0;j=(j-1)&i)
48                 dp[i]=min(dp[i],dp[j]+dp[i^j]);
49         }
50 
51         cout<<dp[all]<<endl;
52     }
53 
54     return 0;
55 }
[C++]
原文地址:https://www.cnblogs.com/lzj-0218/p/3229452.html