zoukankan      html  css  js  c++  java
  • 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++]
  • 相关阅读:
    获取文件扩展名的几个函数
    Window下,在TEMP路径下生成一个临时文件名
    字符串中的TOUPPER函数
    字符串中的TRIM操作
    BIN转换成HEX格式及HEX转换成BIN的两个函数接口
    GMSSL在Window下的编译
    VS2012下自定义打开文件对话框
    Daliy Algorithm (graph,思维)-- day 59
    Daliy Algorithm (贪心,gcd)-- day 58
    图论--Floyd(弗洛伊德)算法
  • 原文地址:https://www.cnblogs.com/lzj-0218/p/3229452.html
Copyright © 2011-2022 走看看