HDU 4628 Pieces(状态压缩DP)

题目链接:传送门

题意:

给定一个长度小于16的字符串然后每次可以去掉它的一个回文子序列,问最少删除多少次可以使这个字符串为空。

分析:

首先预处理出这个字符串的所有回文子序列,然后将其压缩成二进制x,然后dp[x]表示这个序列删除所需要的最小的步数,然后dp[x] = min(dp[x],dp[sub])sub表示x的所有子序列。

代码如下:

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1<<17;

const int inf = 0x3f3f3f;

int dp[maxn];

int check(string s){
    int n = s.length();
    for(int i=0,j=n-1;i<j;i++,j--)
        if(s[i]!=s[j])
            return 0;
    return 1;
}

void init(string str){
    int len = str.length();
    for(int i=1;i<(1<<len);i++){
        string tmp;
        int cnt = 0;
        for(int j=0;j<len;j++){
            if((1<<j)&i)
                tmp=tmp+str[j],cnt++;
        }
        if(check(tmp)){
            dp[i]=1;
        }
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        string str;
        cin>>str;
        memset(dp,inf,sizeof(dp));
        init(str);
        dp[0]=0;
        int len = str.length();
        for(int i=1;i<(1<<len);i++){
            for(int j=i;j>0;j=i&(j-1)){//枚举所有的子状态。
                dp[i]=min(dp[i],dp[i-j]+dp[j]);
            }
        }
        printf("%d\n",dp[(1<<len)-1]);
    }
    return 0;
}
/****
123
aaaaaaaaaa
aaabb
***/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 06:30:39

HDU 4628 Pieces(状态压缩DP)的相关文章

hdu 4568(状态压缩dp)

题意:一张n*m的网格内每个点有话费,还有若干个宝藏,问一个人要走进去拿走所有宝藏在走出来的最小花费. 思路:看宝藏只有13个直接想到了状压dp[i][j]拿了哪几个前一个为j的最小花费,先bfs+优先队列预处理出最短路,然后记忆化搜索就可. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao

HDU 3001【状态压缩DP】

题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的. 然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值. 状态转移也一目了然,不废话. #include<stdio.h> #include<string.h> #include<algorithm> u

hdu 3502 bfs+状态压缩dp

题意是给你n*m的矩阵     每个单位有一个数,-1表示不能走   >=0表示有有多少个能量能获得    问从左上角到右下角能获得的做大能量值(走一步消耗1单位能量) 思路:  先bfs求出所有线之间的最短距离(当然  有用的只有有能量值的点和起点,终点) 然后状态压缩dp  找到最大能量值    这里有几个注意的地方 状态尽量从1开始    减少数组的空间(爆了一次)   其次是bfs是只搜有能量的点     其它都差不多: #include<stdio.h> #include<

hdu 3681 二分+状态压缩dp+bfs

题意就不用多说了,开始想直接bfs+二分简化下做试试   果断超时,然后不得不用状态压缩dp(其实一开始就想这样做的,15个点   每个点都能走多次   绝逼状态压缩dp) 先bfs跑每个关键点之间的做短路径    再二分起点的能量值               状态压缩dp来判断     不说了    AC吧!!!!! #include<stdio.h> #include<string.h> #include<queue> #include<iostream&g

HDU 3001 Travelling 状态压缩dp+3进制

题意:一个人要旅行,他要去n个地方,且这n个地方每个地方最多可以走2次: 给m条路径,寻问最短花费 很明显的状态压缩,但是要求每个点最多只能走两次,就没办法标记当前点走过或是没走过,只能用三进制来表示 1代表地点1被走过一次. 2代表地点1被走过两次. 3(即10)代表地点2被走过一次. 4(即11)代表地点1被走过一次,地点2被走过一次. 5(即12)代表地点1被走过两次,地点2被走过一次. 附AC代码 #include<stdio.h> #include<string.h> i

HDU 3001(状态压缩DP)

题意:遍历所有的城市的最短路径,每个城市最多去两遍.将城市的状态用3进制表示. 状态转移方程为 dp[NewS][i]=min( dp[NewS][i],dp[S][j]+dis[i][j]) S表示遍历点的状态,i表示到达第i个城市. 在到第i个城市的时候看是否存在一个j城市的路径,然后再从j到i更短. #include <algorithm> #include <cstdio> #include <cstring> #define Max 1000001 #defi

[状压dp] hdu 4628 Pieces

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4628 Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1665    Accepted Submission(s): 862 Problem Description You heart broke into pieces

HDU 1565 方格取数(1) (状态压缩DP)

HDU 1565 方格取数(1) (状态压缩DP) ACM 题目地址: HDU 1565 方格取数(1) 题意: 中文. 分析: dp[i][j]表示前i行状态j的最优解. 先预处理出符合条件的数,17000+个(n在20以内). 不过感觉复杂度挺高的会T,但是却能A. 这题的正解应该是最小割,回头补下. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1565_dp.cpp * Create Date: 2014-09-19 23

hdu 3217 Health(状态压缩DP)

Health Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 527    Accepted Submission(s): 145 Problem Description Unfortunately YY gets ill, but he does not want to go to hospital. His girlfriend LM