HDOJ-5677 ztr loves substring
2016-05-01 16:23
357 查看
用manacher 求出每个串的所有子串长度,然后把每个子串当作物品,费用为长度,和个数,就可以当作二维费用的多重背包来解。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100005 using namespace std; bool dp[105][105]; int p[105], len[105<<1]; char str[105], ans[105<<1]; void Manacher(){ int mex = 0, id; for(int i = 1; ans[i]; i++){ if(mex > i) len[i] = min(len[2*i-id], mex-i); else len[i] = 1; while(ans[i+len[i]] == ans[i-len[i]]) len[i]++; if(mex < i + len[i]){ id = i; mex = i + len[i]; } } for(int i = 1; ans[i]; i++){ for(int j = len[i]-1; j > 0; j -= 2) p[j]++; } } void Init(){ scanf("%s", str); int d = 1; ans[0] = '@'; for(int i = 0; str[i]; i++){ ans[d++] = '#'; ans[d++] = str[i]; } ans[d++] = '#'; ans[d] = 0; Manacher(); } int main(){ // freopen("in.txt", "r", stdin); int t; cin >> t; while(t--){ int n, k, l; scanf("%d%d%d", &n, &k, &l); memset(p, 0, sizeof(p)); memset(dp, false, sizeof(dp)); for(int i = 0; i < n; i++) Init(); dp[0][0] = true; for(int i = 1; i <= l; i++){ int h; for(h = 1; h <= p[i]; h << 1, p[i] -= h) for(int j = l; j >= h*i; j--) for(int e = h; e <= k; e++){ dp[j][e] |= dp[j-h*i][e-h]; } if(p[i]){ h = p[i]; for(int j = l; j >= i*h; j--) for(int e = h; e <= k; e++) dp[j][e] |= dp[j-i*h][e-h]; } } if(dp[l][k]) cout << "True" << endl; else cout << "False" << endl; } return 0; }
相关文章推荐
- 异常 dubbo demo中 consumer消费的问题
- apache+jkmount+tomcat
- 剑指offer(64):序列化二叉树
- HTTP请求
- 安卓java.lang.IllegalArgumentException: The observer is null.解决方案
- 杨辉三角形
- 安卓java.lang.IllegalArgumentException: The observer is null.解决方案
- NSDictionary转NSData【相互转换】
- CentOs 7.0安装JDK、MySQL和Tomcat
- 基本登录页面的实现
- tomcat和apache连接器mod_jk (tomcat connectors)
- 实现Struts2中对未登录的jsp页面进行拦截功能(采用的是Struts2中过滤器进行过滤拦截)
- maven快速入门
- 【LeetCode】Climbing Stairs 解题报告
- 九 AIDL
- 第 30 章 使用 Emmet 插件
- 确定Java开发中.jar包的JDK版本
- iOS自定义progressView的实现
- Cocos2d-js 音乐or音效
- 创业哲学