题意:给一个长度为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 ;
}

最新文章

  1. SQL SERVER修改函数名引起的问题
  2. Linux内核--内核数据类型
  3. Unity学习疑问记录之查找
  4. html给div加超链接的方法
  5. 手机页面中的meta标签
  6. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 模拟
  7. uboot各种目录下的文件作用
  8. PHP $_GET 变量
  9. 前端获取checkbox复选框的值 通过数组形式传递
  10. ubuntun与qt下载地址
  11. warning C4996: &#39;strcpy&#39;: This function or variable may be unsafe.
  12. Vue项目启动后首页URL带的#该怎么去掉?
  13. Android平台上最好的几款免费的代码编辑器
  14. Java知多少(74)基础类库
  15. db2 查杀死锁进程
  16. InstallShield安装jdk并设置环境变量
  17. Python开发之用户密码存储
  18. 撩课-Java每天5道面试题第18天
  19. Python中级 —— 03进程与线程
  20. brew install memcache get Error: Formulae found in multiple taps

热门文章

  1. mapstruct使用详解
  2. Springboot:员工管理之国际化(十(3))
  3. 微信小程序标签常见知识点归纳整理
  4. Java 排序算法-冒泡排序及其优化
  5. Visual Studio 添加图标和版本
  6. SpringBoot应用操作Rabbitmq(topic交换器高级操作)
  7. (转)logback配置详解
  8. Retrofit的文件上传和进度提示
  9. caffe学习笔记(1)安装 - Ubuntu 15.04
  10. Node Mysql事务处理封装