hdu 4628 Pieces(状态压缩+DP,4级)

Pieces

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 101    Accepted Submission(s): 54

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
 
Recommend
zhuyuanchen520
 

思路:才16个字符,状态压缩下,判判回文,然后一个记忆化DP搞定。

失误点:1<<t需要加括号。

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define FOR(i,a,b) for(int i=a;i<=b;++i)
 6 #define clr(f,z) memset(f,z,sizeof(f))
 7 #define shift(t) (1<<t)
 8 using namespace std;
 9 const int oo=1e9;
10 const int mm=25;
11 const int nn=(1<<16)+9;
12 char ks[mm],sa[mm],sb[mm],lsa,lsb,sc[mm];
13 int has[nn],dp[nn];
14 int num[nn],pos;
15 int cas;
16 bool ok(char*s,int x)
17 { int len=strlen(s);
18   lsa=lsb=0;
19   FOR(i,0,len-1)
20   {
21     if((x&shift(i))!=0)
22     {
23       sa[lsa++]=s[i];
24     }
25     else sb[lsb++]=s[i];
26   }
27   int l=0,r=lsa-1;bool flag=1;
28   while(l<=r)
29   {
30     if(sa[l++]!=sa[r--]){flag=0;break;}
31   }
32   sb[lsb]='\0';
33   if(flag)return 1;
34   else return 0;
35 }
36 
37 int DP(int x)
38 { if(x==0)return 0;
39   if(dp[x]!=-1)return dp[x];
40   if(has[x])return 1;
41   int ret=9999;
42   FOR(i,0,pos-1)
43   {  if(num[i]>x)break;
44     if(((num[i]|x)==x))
45     ret=min(ret,DP(x-num[i]));
46   }
47   dp[x]=ret+1;
48   return dp[x];
49 }
50 
51 int get(char*s)
52 { clr(has,0);
53   int len=strlen(s);
54   pos=0;
55   FOR(i,1,shift(len)-1)
56   if(ok(s,i))
57     {has[i]=1;num[pos++]=i;}
58   clr(dp,-1);
59   //FOR(i,0,shift(len))dp[i]=oo;
60  int ans=DP(shift(len)-1);
61  return ans;
62 }
63 int main()
64 {
65   while(~scanf("%d",&cas))
66   {
67     while(cas--)
68     {
69       scanf("%s",ks);
70       get(ks);
71       printf("%d\n",get(ks));
72     }
73   }
74   return 0;
75 }
View Code

非递归版

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define FOR(i,a,b) for(int i=a;i<=b;++i)
 6 #define clr(f,z) memset(f,z,sizeof(f))
 7 #define shift(t) (1<<t)
 8 using namespace std;
 9 const int oo=1e9;
10 const int mm=25;
11 const int nn=(1<<16)+9;
12 char ks[mm],sa[mm],sb[mm],lsa,lsb,sc[mm];
13 int has[nn],dp[nn];
14 int cas;
15 bool ok(char*s,int x)
16 { int len=strlen(s);
17   lsa=lsb=0;
18   FOR(i,0,len-1)
19   {
20     if((x&(shift(i)))!=0)
21     {
22       sa[lsa++]=s[i];
23     }
24     else sb[lsb++]=s[i];
25   }
26   int l=0,r=lsa-1;bool flag=1;
27   while(l<=r)
28   {
29     if(sa[l++]!=sa[r--]){flag=0;break;}
30   }
31   sb[lsb]='\0';
32   if(flag)return 1;
33   else return 0;
34 }
35 int get(char*s)
36 { clr(has,0);
37   int len=strlen(s);
38   FOR(i,1,shift(len)-1)
39   if(ok(s,i))
40     {has[i]=1;}
41   //if(has[shift(len)-1])puts("oo");
42   FOR(i,0,shift(len))dp[i]=oo;
43        dp[0]=0;
44         FOR(j,1,(1<<len)-1)
45         {
46             dp[j]=0;
47             FOR(i,0,len-1)
48             if(j&(1<<i))
49               dp[j]++;
50             if (has[j])
51             {
52                 dp[j]=1;
53                 continue;
54             }
55             for (int x=j;x;x=(x-1)&j)
56             {
57                 if (has[j^x])
58                 {
59                     dp[j]=min(dp[j],dp[x]+1);
60                 }
61             }
62 
63         }
64  return dp[(1<<len)-1];
65 }
66 int main()
67 {
68   while(~scanf("%d",&cas))
69   {
70     while(cas--)
71     {
72       scanf("%s",ks);
73      // if(ok(ks,15))puts("oo");
74       printf("%d\n",get(ks));
75     }
76   }
77   return 0;
78 }
View Code

 

posted @ 2013-07-30 18:46  剑不飞  阅读(565)  评论(0编辑  收藏  举报