• hdu 4628 Pieces 状态压缩dp


    Pieces

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

    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
     
     
    这一题的对字符串的回文判断是可以想到的。
    关键在于如果更新它,这里有技巧。
    看了别人的题解 ,过的这道题。当时觉得没有思路,现在返回去看。
    有一个地方是很值得学习的。
    思路:
       1.预处理,求出输入的串的子串中,那些满足回文情况。
       2.更新,dp[1<<k]。

      for(i=1;i<k;i++)//枚举每一种情况。
      {
         for(j=i;j>=1;j--)//对于每一种情况,首选就是它自身了。
        {
          if(flag[j])//判断是否为回文情况
             {
             if(dp[i-j]+1<dp[i])
             dp[i]=dp[i-j]+1;//更新
             }
           j=i&j;//这句很重要
        }
      }

     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 
     7 char a[20];
     8 int dp[1<<21];
     9 bool flag[1<<21];
    10 void solve(int n)
    11 {
    12     int i,j,k,ans,len;
    13     int f[20];
    14     k=1<<n;
    15     for(i=0;i<k;i++)//预处理
    16     {
    17         ans=0;
    18         for(j=0;j<=16;j++)
    19         if( (i&(1<<j))>0)
    20             f[++ans]=j;
    21         len=ans/2;
    22 
    23         for(j=1;j<=len;j++)
    24         if( a[f[j]]!=a[f[ans-j+1]]) break;
    25         if(j>len) flag[i]=true;
    26         else flag[i]=false;
    27     }
    28     for(i=1;i<k;i++)
    29     dp[i]=16;
    30     dp[0]=0;
    31     for(i=1;i<k;i++)
    32     {
    33         for(j=i;j>=1;j--)
    34         {
    35             if(flag[j])
    36             {
    37                 if(dp[i-j]+1<dp[i])
    38                 dp[i]=dp[i-j]+1;
    39             }
    40             j=i&j;
    41         }
    42     }
    43     printf("%d
    ",dp[k-1]);
    44 }
    45 int main()
    46 {
    47     int T,n;
    48     while(scanf("%d",&T)>0)
    49     {
    50         while(T--)
    51         {
    52             scanf("%s",a);
    53             n=strlen(a);
    54             solve(n);
    55         }
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    “图灵&博客园&互动网有奖书评征集活动——微软技术系列”评选结果
    像优秀的SQL程序员一样思考
    倚天·屠龙——唯我独尊
    CSS与HTML设计模式全集(350余种)
    游览器兼容冲突的常见css
    嵌入多媒体文本
    删除确认代码
    用!important解决IE和Mozilla的布局差别
    四大游览器兼容问题综合实例
    jQuery事件之鼠标事件
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3424414.html
Copyright © 2020-2023  润新知