题意:给一个长度为16的字符串,每次从里面删掉一个回文序列,求最少需要几次才能删掉所有字符

思路:二进制表示每个字符的状态,那么从1个状态到另一个状态有两种转移方式,一是枚举所有合法的回文子序列,判断是否是当前状态的子状态,再转移,二是枚举当前状态的所有子状态来转移。前者最坏复杂度O(2^16*2^16) = O(几十亿),而后者最坏只有(i:1->16)Σ2iC(16,i) = O(几千万)。

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; #ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=;i<a.size();i++)a[i]=b[i];} const double PI = acos(-1.0);
const int INF = 1e9 + ; /* -------------------------------------------------------------------------------- */ char s[];
int n, dp[ << ]; void init() {
for (int i = ; i < ( << n); i ++) dp[i] = INF;
dp[] = ;
for (int i = ; i < ( << n); i ++) {
int j, k;
for (j = n - ; j >= ; j --) {
if (i & ( << j)) break;
}
for (k = ; k < n; k ++) {
if (i & ( << k)) break;
}
if (s[j] == s[k] && dp[i ^ ( << j) ^ ( << k)] < INF)
dp[i] = dp[i ^ ( << j) ^ ( << k)];
if (j == k) dp[i] = ;
}
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T;
cin >> T;
while (T --) {
scanf("%s", s);
n = strlen(s);
init();
for (int i = ; i < ( << n); i ++) {
for (int j = i; j; j = (j - ) & i) {
umin(dp[i], dp[i ^ j] + dp[j]);
}
}
cout << dp[( << n) - ] << endl;
}
return ;
}

[hdu4628 Pieces]二进制子状态,DP的更多相关文章

  1. poj3254二进制放牛——状态压缩DP

    题目:http://poj.org/problem?id=3254 利用二进制压缩状态,每一个整数代表一行的01情况: 注意预处理出二进制表示下没有两个1相邻的数的方法,我的方法(不知为何)错了,看到 ...

  2. hdu 4614 pieces 状态DP

    题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...

  3. poj-3666 【对dp子状态无后效性的理解】

    题目链接 错解: #include <cstdio> #include <cstring> #include <algorithm> #include <io ...

  4. 点集配对问题(状态dp)

    给定n个点(n是偶数)使得两个点两两配对,最后总的距离和最小. 用是表示集合,那么dp[s]表示集合s配对后的最小距离和  , 状态转换方程为  表示集合中任意拿两个元素配对,然后转移为更小的两个集合 ...

  5. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  6. hdu 5135(2014广州—状态dp)

    t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积 ...

  7. POJ 1185 状态DP

    这个题目是个挺难表示的状态DP,因为不但要考虑上下还要考虑左右,在DP里面就没有什么下了咯,但也至少除了考虑左右还要考虑上 所以先枚举出在同一行满足条件的状态 即 某状态 若 s&(s< ...

  8. POJ 3254 压缩状态DP

    题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围, ...

  9. 【状态DP】 HDU 1074 Doing Homework

    原题直通车:HDU  1074  Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样 ...

随机推荐

  1. 最短路径变形 POJ 2253

    Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sit ...

  2. 【原创干货】大数据Hadoop/Spark开发环境搭建

    已经自学了好几个月的大数据了,第一个月里自己通过看书.看视频.网上查资料也把hadoop(1.x.2.x).spark单机.伪分布式.集群都部署了一遍,但经历短暂的兴奋后,还是觉得不得门而入. 只有深 ...

  3. 今天开始让我们一起来学JavaScript吧!(今天先扯先别的)

    1.为什么要学习JavaScript? 首先它是web开发人员必须学习的3门语言之一: ①HTML定义了网页的内容 ②CSS描述了网页的布局: ③JavaScript网页的行为 首先JavaScrip ...

  4. Element里el-badge在el-tab里视图不被渲染问题

    我们发现:el-badge绑定的变量是有数据的,但是界面上就是不渲染. 这个时候执行getTodo发现数据已经打印出来,当是视图未发送变化.于是查阅资料:vm.$forceUpdate()示例:迫使 ...

  5. 负载均衡服务之HAProxy基础配置(三)

    前文我们聊到了haproxy的代理配置段中比较常用的配置指令的用法以及说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12770930.html:今天我们来 ...

  6. 005.Ansible de palybook简单使用

    一 Ansible Playbook简介 ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写.playbook命令根据自上而下的顺序依次执行.同时,playboo ...

  7. php正则验证手机、邮箱

    //验证电话private function reg_phone($phone){        if (preg_match("/^13[0-9]{1}[0-9]{8}$|15[0189] ...

  8. 【Python可视化】使用Pyecharts进行奥运会可视化分析~

    项目全部代码 & 数据集都可以访问我的KLab --[Pyecharts]奥运会数据集可视化分析-获取,点击Fork即可- 受疫情影响,2020东京奥运会将延期至2021年举行: 虽然延期,但 ...

  9. 2019-2020-1 20199303《Linux内核原理与分析》第六周作业

    系统调用的三层机制 首先是为系统增加新的命令 运行脚本自动生成文件系统 其中有一个显示时间的功能 编辑test.c文件,增加一个hello函数用来显示学号,再次使用make roofts自动编译,调用 ...

  10. 面向对象(OO)第二阶段学习总结

    0.前言 此阶段总共进行三次大作业,其中第一次作业中的第一题,水文数据校验及处理中,遇到较大的难题,第一次接触正则表达式,编码过程中显得难度特别大.第二次作业同样也是对于一元多项式求导中对单项的正则校 ...