zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    014-CallbackServlet代码
    PaymentServlet代码
    013-PaymentUtils工具类模板
    案例30-在线支付
    案例29-购物车提交订单
    案例28-清空购物车
    案例27-购物车删除单一商品
    案例26-购物车
    案例25-servlet的抽取
    在Eclipse或工作空间中 ,复制或修改项目后,把项目部署后发现还是原来的项目名称
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3424414.html
Copyright © 2011-2022 走看看