zoukankan      html  css  js  c++  java
  • HDU 4628 Pieces

    Pieces

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

    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
     

    题意:

            给定一个串,每次可以删除一个回文子串,问把全串删干净的最少次数。

            这里的字串任意选,不要求连续。

    思路: 看到S<=16可能条件反应可以状态压缩了,仔细一看还真是,对于每个状态可以枚举子集串,枚举子串是老生常谈的

           算法了,这里详细写一下。比如 abcd 有4个数码,对于每个数码可以选也可以不选,一共2^4种,“” ,a ,b ,c ,d',ab ....abcd

           当然了,空子串排除,那么总共的字串是2^串长-1 ,将串“映射”成数字,比如a-->1000 ,b--->0100 ,c-->0010 ,ad--1001 ,

           adcd-->1111 ,这样做即可把所有的子串枚举出来。但是此题要求字串为回文,这只需要稍加判断即可,啰嗦一句,其实STL

           熟悉了是比较方便编码的,不要太过于排斥STL 。

               DP的部分就是个类似背包了 。注意代码里的一点  j&=i ,j表示字串 ,I 表示母串 ,如果注释j&=i ,会TL 。

          举个例子吧。比如i=100000 , 事实上字串只有100000 。只需要枚举100000即可, 如10100 ,只需枚举10100 ,10000 ,00100

          即可,j=j&i 起到加速作用(不要太过于纠结这里,可能上厕所的时候就恍然大悟了), 可以用笔画一下。

     
    #include <iostream>
    #include <string.h>
    #include <string>
    #include <algorithm>
    #include <stdio.h>
    #include <queue>
    #include <set>
    #include <limits.h>
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std ;
    struct Me{
       string str ;
       int is_palindrome[(1<<16)+10] ;
       int dp[(1<<16)+10] ;
       Me(){}
       Me(string s):str(s){}
       void get_is_palindrom(){
          memset(is_palindrome,0,sizeof(is_palindrome)) ;
          for(int i=1;i<(1<<str.length());i++){
             vector<int>vec ;
             vec.clear() ;
             for(int j=0;j<str.length();j++){
                if(i&(1<<j))
                    vec.push_back(j) ;
             }
             int k ;
             for(k=0;k<vec.size();k++){
                if(str.at(vec[k])!=str.at(vec[vec.size()-k-1]))
                     break ;
             }
             if(k==vec.size())
                is_palindrome[i]=1 ;
          }
       }
       void DP(){
           get_is_palindrom() ;
           fill(dp,dp+(1<<str.length()),16) ;
           dp[0]=0 ;
           for(int i=1;i<(1<<str.length());i++){
              for(int j=i;j>=1;j--){
                  if(is_palindrome[j])
                      dp[i]=Min(dp[i],dp[i-j]+1) ;
                  j&=i ;   //这个注意
    } } } int gao_qi(){ DP() ; return dp[(1<<str.length())-1] ; } }; int main(){ int T ; string s ; cin>>T ; while(T--){ cin>>s ; Me me(s) ; cout<<me.gao_qi()<<endl ; } return 0 ; }
     
  • 相关阅读:
    C#数据结构与算法系列(十三):递归——迷宫问题
    C#数据结构与算法系列(十二):递归(Recursion)
    C#数据结构与算法系列(十一):中缀表达式转后缀表达式
    C#数据结构与算法系列(十):逆波兰计算器——逆波兰表达式(后缀表达式)
    Quartz.Net系列(八):Trigger之CalendarIntervalScheduleBuilder详解
    Quartz.Net系列(七):Trigger之SimpleScheduleBuilder详解
    C#数据结构与算法系列(九):栈实现综合计算器(中缀表达式)
    Redis系列(五):数据结构List双向链表源码解析和API实现
    Quartz.Net系列(六):Quartz五大构件Trigger之TriggerBuilder解析
    C#数据结构与算法系列(八):栈(Stack)
  • 原文地址:https://www.cnblogs.com/liyangtianmen/p/3227246.html
Copyright © 2011-2022 走看看