HDU 5763 Another Meaning

题意:一个字串有可能在模式串出现多次,问有多少种可能出现的情况。关键是有重合的字串是不能同时计入的。

思路:先用kmp求出所有字串的位置。然后,dp.

二维的时候:dp[i][j] i表示前i个子串,j的值1表示一定用这个串,0表示不用。值表示字串出现的情况数。

一维的时候可以直接用dp[i] 表示前i个字串能出现的情况。

然后,状态转移就都是分为三种情况:

1)当前子串和前一个子串不冲突,dp[i] = dp[i-1] * 2. 或者 dp[i][0] = dp[i-1][1] + dp[i-1][0] = dp[i][1] = dp[i-1][1].

2) 当前子串和前一个冲突,那就不一定是只和前一个冲突,所以从i-2开始寻找直到找到不冲突的j,有 dp[i] = dp[i-1] + dp[j]. 或者  dp[i][0] = dp[i-1][1] + dp[i-1][0] , dp[i][1] = dp[j][0] + dp[j][1].

3) 当前子串没找到上述的j子串,那么dp[i] = dp[i-1] + 1. 或者 dp[i][1] = 1.

二维代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
const int mod=1000000007;
vector <int> ans; vector <int> find_substring(string pattern, string text) {
int n = pattern.size();
vector <int> nxt(n+1, 0);
for (int i=1; i<n; ++i) {
int j = i;
while(j > 0) {
j = nxt[j];
if (pattern[j] == pattern[i]) {
nxt[i+1] = j + 1;
break;
}
}
} vector <int> positions;
int m = text.size();
for (int i=0, j=0; i<m; ++i) {
if (j<n && text[i] == pattern[j]) {
j++;
}else {
while (j>0) {
j = nxt[j];
if (text[i] == pattern[j]) {
j++;
break;
}
}
}
if (j == n) {
positions.push_back(i-n+1);
}
}
return positions;
} int dp[100005][2]; // dp[i][1] 表示前i个串一定用上第i个时 maxans dp[i][0] 表示前i个串的时候不用第i个时候的ans. int main() {
int t;
//freopen("in.cpp", "r", stdin);
cin >> t;
string str1, str2;
int cas = 0;
while(t--) {
ans.clear();
cin >> str1 >> str2;
ans = find_substring(str2, str1);
int tot = ans.size();
if (tot == 0) {
printf("Case #%d: %d\n", ++cas, 1);
continue;
} dp[0][0] = 1;
dp[0][1] = 1; for (int i=1; i<tot; ++i) {
dp[i][0] = ((dp[i-1][0]%mod) + (dp[i-1][1]%mod))%mod;
bool flag = false;
for (int j=i-1; j>=0; --j) {
if (ans[i] - ans[j] >= str2.length()) {
dp[i][1] = ((dp[j][1]%mod) + (dp[j][0]%mod)) % mod;
flag = true;
break;
}
} if (flag == false) {
dp[i][1] = 1;
}
}
// if(ans[i]-ans[i-1]>=str2.length())dp[i][1]=(dp[i][1]%mod+dp[i-1][1]%mod)%mod;
printf("Case #%d: %d\n", ++cas, ((dp[tot-1][1]%mod)+(dp[tot-1][0]%mod))%mod);
}
return 0;
}

一维代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
const int mod=1000000007;
vector <int> ans; vector <int> find_substring(string pattern, string text) {
int n = pattern.size();
vector <int> nxt(n+1, 0);
for (int i=1; i<n; ++i) {
int j = i;
while(j > 0) {
j = nxt[j];
if (pattern[j] == pattern[i]) {
nxt[i+1] = j + 1;
break;
}
}
} vector <int> positions;
int m = text.size();
for (int i=0, j=0; i<m; ++i) {
if (j<n && text[i] == pattern[j]) {
j++;
}else {
while (j>0) {
j = nxt[j];
if (text[i] == pattern[j]) {
j++;
break;
}
}
}
if (j == n) {
positions.push_back(i-n+1);
}
}
return positions;
} int dp[100005]; int main() {
int t;
//freopen("in.cpp", "r", stdin);
cin >> t;
string str1, str2;
int cas = 0;
while(t--) {
ans.clear();
cin >> str1 >> str2;
ans = find_substring(str2, str1);
int tot = ans.size();
if (tot == 0) {
printf("Case #%d: %d\n", ++cas, 1);
continue;
} dp[0] = 2;
for (int i=1; i<tot; ++i) {
if (ans[i]-ans[i-1]>=str2.length()) {
dp[i] = (dp[i-1]*2)%mod;
}
else {
bool flag = true;
for (int j=i-2; j>=0; --j) {
if (ans[i] - ans[j] >= str2.length()) {
dp[i] = (dp[j] + dp[i-1])%mod;
flag = false;
break;
}
}
if (flag) dp[i] = (dp[i-1] + 1)%mod;
}
} printf("Case #%d: %d\n", ++cas, dp[tot-1]%mod);
}
return 0;
}

体验:dp无处不在..dp大法好... >_<

HDU 5763 Another Meaning的更多相关文章

  1. HDU 5763 Another Meaning KMP+DP

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 Another Meaning Time Limit: 2000/1000 MS (Java/ ...

  2. HDU 5763 Another Meaning (kmp + dp)

    Another Meaning 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 Description As is known to all, ...

  3. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

  4. HDU 5763 Another Meaning(FFT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5763 [题目大意] 给出两个串S和T,可以将S串中出现的T替换为*,问S串有几种表达方式. [题解 ...

  5. HDU 5763 Another Meaning(DP+KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=5763 题意: 给出一个字符串和一个模式串,模式串有两种意思,问这句话有几种意思. 思路:因为肯定要去字符串去找模 ...

  6. HDU 5763 Another Meaning dp+字符串hash || DP+KMP

    题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe   sub:hehe 那么,有**he.he** ...

  7. TTTTTTTTTTTTTT hdu 5763 Another Meaning 哈希+dp

    Another Meaning Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  8. HDU 5763 Another Meaning (KMP/哈希+DP)

    题目大意:给你两个串,一长一短,如果长串中某个子串和短串完全相同,则这个子串可以被替换成"#",求长串所有的表达形式....... 比如"hehehehe"和& ...

  9. HDU 5763:Another Meaning(字符串匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=5763 Another Meaning Problem Description   As is known to ...

随机推荐

  1. pfx,cer转pem,并对通过pem文件进行签名与验签

    因为PHP无法读取.pfx文件,所以可以先转换为.pem文件然后在读取里面的数据,可以读取.cer文件,为了两方面统一,就都换成.pem然后再进行加签和验签. sign.php <?php de ...

  2. Eclipse使用Jetty(转)

    eclipse 与 jetty 结合的最佳实践 http://www.cnblogs.com/mignet/archive/2011/12/04/eclipse_jetty_perfect_integ ...

  3. Git学习(1)Git 简介

    Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件. Git ...

  4. 【Todo】用python进行机器学习数据模拟及逻辑回归实验

    参考了这个网页:http://blog.csdn.net/han_xiaoyang/article/details/49123419 数据用了 https://pan.baidu.com/s/1pKx ...

  5. 3 javascript

    3 javascript javascript基础 html: 负责了一个页面的结构.   css: 负责了一个页面的样式.    javascript: 负责与用户进行交互. 1997年欧洲的计算机 ...

  6. 青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

    题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 ...

  7. Linux下的split 命令(将一个大文件根据行数平均分成若干个小文件)

    将一个大文件分成若干个小文件方法 例如将一个BLM.txt文件分成前缀为 BLM_ 的1000个小文件,后缀为系数形式,且后缀为4位数字形式 先利用 wc -l BLM.txt       读出 BL ...

  8. IE浏览器GET传参后台乱码

    ie里面 get传递的字符串 为 gb2312  ,后台用的是utf-8类型  所以用 POST传递字符串到后端 否则进行js参数转码 encodeURI(""); 后端解码

  9. 各种element/format 在manage display 下的选项

    long text = > plain text, summary and trimmed, trimmed,default, hiddenentity refernece => enti ...

  10. QQ等级图标排名说明_QQ等级表,QQ最高等级(皇冠) qq到一星要5天

    从2007年11月29日中午12:00开始,在不改变原有计算方式的情况下,加速QQ会员等级升级.QQ会员用户在原有通过每天在线2小时累积活跃天数来获取相应QQ等级增长的基础上,还可以根据QQ会员VIP ...