【NOIP2015】 Day2 T2 字串 (多维动归)
2018-09-12
原题传送门(洛谷)https://www.luogu.org/problemnew/show/P2679
模拟考试的时候完全没有想到 正确的DP方程呢
本来写了一个大致是对的转移方程 结果算了一下空间 大概不够 就放弃了(第一维可以滚动 掉的啊喂 傻孩子啊) 愣是写了50分暴力
下面是五十分的原代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring> #define For(i,a,b) for(register int i=a;i<=b;++i)
#define Dwn(i,a,b) for(register int i=a;i>=b;--i)
#define Re register using namespace std;
const int md=1e9+; int na,nb,kx;
string As,Bs;
int sum=;
char c[];
int cf[]; int main(){
// freopen("ex2.in","r",stdin);
freopen("substring.in","r",stdin);
freopen("substring.out","w",stdout);
cin>>na>>nb>>kx;
cin>>As; cin>>Bs;
if(kx==){
int px=;
while(){
int p=As.find(Bs,px);
if(p==-)break;
sum++; px=p+;
if(sum>=md)sum%=md;
}
cout<<sum%md<<endl; return ;
}
if(kx==){
string s1,s2;
For(i,,nb-){
s1=""; s2="";
For(j,,i)s1=s1+Bs[j];
For(j,i+,nb-)s2=s2+Bs[j];
// cout<<s1<<" "<<s2<<" "<<sum<<endl; int px1,px2;
int sum2=;
px1=px2=; while(){
int p1=As.find(s1,px1);
if(p1==-)break;
sum2=;
px2=p1+s1.size();
if(p1>na-)break;
while(){
int p2=As.find(s2,px2);
if(p2==-)break;
sum2++; px2=p2+;
if(sum2>=md)sum2%=md;
}
sum+=sum2; if(sum>=md)sum%=md;
px1=p1+;
}
}
cout<<sum%md<<endl;
return ;
}
if(kx==nb){
For(i,,nb-)c[i+]=Bs[i],cf[i+]=;
For(i,,na-){
char ac=As[i];
Dwn(j,nb,){
if(ac==c[j]){
if(j==)cf[j]++;
else cf[j]+=cf[j-];
cf[j]%=md;
}
}
}
sum=cf[nb]%md;
cout<<sum<<endl;
return ;
}
}
当k=1,(即只能分一个字串) 直接s.find()去搜就好了
当k=2,(即分两个字串)还是暴力用find()去搜
然后 当k=m (即与B串等长)想了一个挺巧妙的方法。。 用 cf[i] 数组表示此时的B串前 i 位的方案数 按顺序 考虑 A串的一个字符
从后往前枚举 i 当 A[j]== B[i] cf[i]+=cf[i-1] (算了算了都是暴力 不看也罢
正确 方法
多维动归 !
用我们 奥赛教练的话来说就是
每次只要一考到 多维动归 我就替学生捏一把汗 这道题是能否拿到绝对高分的关键!!
然鹅 模拟测试时我没做出来呢
好了 下面正经写题解
DP数组 f[i][j][k][0/1] 表示A的前i位 B的前j位 用了k个字串 A的第i个字串是否使用的方案数
那么我们很容易就可以得到转移方程
A[i]==B[j]
1. 不取(0)f[i][j][k][0] <-- f[i-1][j][k][0] + f[i-1][j][k][1]
2. 取 (1)f[i][j][k][1] <-- f[i-1][j-1][k][1] (与前方字符连成一个字串)+ f[i-1][j-1][k-1][1](自己单独另起一串)+ f[i-1][j-1][k-1][0]
A[i]!=B[j]
1. 不取(0)f[i][j][k][0] <-- f[i-1][j][k][0] + f[i-1][j][k][1]
2. 取 显然只能等于 0
初始边界 所有的 f[i][0][0][0]=1
然后愉快地把第一维 i 用滚动数组滚掉即可
复杂度 O(nmk)
附上代码
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm> #define For(i,a,b) for(register int i=a;i<=b;++i)
#define Re register
using namespace std;
const int Na=1e3+,Nb=;
const int md=1e9+;
long long f[][Nb][Nb][];
char A[Na],B[Nb];
int na,nb,kx;
int main(){
// freopen("substring9.in","r",stdin);
// freopen("substring.out","w",stdout);
scanf("%d%d%d",&na,&nb,&kx);
scanf("%s",A+); scanf("%s",B+);
f[][][][]=f[][][][]=;
For(i,,na){
int now=i%;
For(j,,nb) For(k,,kx){
if(A[i]==B[j]){
f[now][j][k][]=(f[now^][j-][k][]+f[now^][j-][k-][]+f[now^][j-][k-][])%md;
f[now][j][k][]=(f[now^][j][k][]+f[now^][j][k][])%md;
}else{
f[now][j][k][]=;
f[now][j][k][]=(f[now^][j][k][]+f[now^][j][k][])%md;
}
}
}
long long fn=f[na%][nb][kx][]+f[na%][nb][kx][];
cout<<fn%md<<endl;
fclose(stdin); fclose(stdout);
return ; }
【NOIP2015】 Day2 T2 字串 (多维动归)的更多相关文章
- 【NOIP2015】字串
[NOIP2015]字串 标签: DP NOIP Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其 ...
- [NOIP2002]字串变换 T2 双向BFS
题目描述 已知有两个字串 A,B 及一组字串变换的规则(至多6个规则): A1−>B1 A2−>B2 规则的含义为:在 A$中的子串 A1可以变换为可以变换为B1.A2可以变换为可 ...
- 2019年华南理工大学程序设计竞赛(春季赛) K Parco_Love_String(后缀自动机)找两个串的相同字串有多少
https://ac.nowcoder.com/acm/contest/625/K 题意: 给出Q 个询问 i , 求 s[0..i-1] 与 s[i...len-1] 有多少相同的字串 分析: 给出 ...
- 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk ...
- 04-String——课后作业1:字串加密
题目:请编写一个程序,加密或解密用户输入的英文字串要求设计思想.程序流程图.源代码.结果截图. 程序设计思想:首先由用户选择是加密还是解密,利用String类中的charAt函数依次取出字串中的字符, ...
- 最大公共字串LCS问题(阿里巴巴)
给定两个串,均由最小字母组成.求这两个串的最大公共字串LCS(Longest Common Substring). 使用动态规划解决. #include <iostream> #inclu ...
- 编程:使用递归方式判断某个字串是否回文(Palindrome)
Answer: import java.util.Scanner; public class Palindrome { private static int len;//全局变量整型数据 privat ...
- NOIP2002字串变换[BFS]
题目描述 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$.A2 ...
- 【BZOJ 4517】【SDOI 2016 Round1 Day2 T2】排列计数
本蒟蒻第一次没看题解A的题竟然是省选$Round1$ $Day2$ $T2$ 这道组合数学题. 考试时一开始以为是莫队,后来想到自己不会组合数的一些公式,便弃疗了去做第三题,,, 做完第三题后再回来看 ...
随机推荐
- SAP bseg 使用注意点:1.不要使用;2.有主键再用,
粗表-簇表 cluster-table BSEGRFBLG 池表 pool-table 我記的沒錯的話,在21天學會ABAP中有一節是專門在講Cluster table,另外在 www.sapfans ...
- RobotFramework教程使用笔记——requests和requestslibrary库
Robotframework也可以进行接口测试,只要导入相应的库就可以做到. 一.准备工作 1.导入requests,使用pip,或者手动下载 pip install requests 2.导入req ...
- sqlserver锁表查看
sp_lock--查询哪个进程锁表了,spid:进程ID,ObjId:对象ID EXEC sp_executesql N'KILL [spid]'--杀进程 select object_name([O ...
- MySQL索引优化-from 高性能MYSQL
Btree: 1. 尽量使用覆盖索引, 即三星索引 2. 多列索引如果带范围的话, 后续列不会作为筛选条件 3. 多列索引应选择过滤性更好的充当前缀索引 4. 尽量按主键顺序插入, 减少页分裂, 采用 ...
- 闪动的Label控件
带闪动效果带控件,目前只有Label,以后会逐步增加,如果有好看带效果也欢迎您带加入. 如果可能,请在github中star,您的支持是我继续完善的动力,非常感谢. 测试环境:Xcode 5.0,iO ...
- cookie(点心的意思)服务器给客户端的点心
他是用户访问web服务器时,服务器在用户硬盘上存放的信息,好像是服务器给客户端的“点心”.比如:是否记录用户名密码.其中,A服务器不允许访问B服务器存在客户端的cookie 一个cookie包含一对k ...
- 第三篇:python基础之数据类型与变量
阅读目录 一.变量 二.数据类型 2.1 什么是数据类型及数据类型分类 2.2 标准数据类型: 2.2.1 数字 2.2.1.1 整型: 2.2.1.2 长整型long: 2.2.1.3 布尔bool ...
- CodeForces - 840D:(主席树求出现区间出现次数大于某值的最小数)
Once, Leha found in the left pocket an array consisting of n integers, and in the right pocket q que ...
- BZOJ_3781_小B的询问_莫队
BZOJ_3781_小B的询问_莫队 Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值 ...
- 使用IIS Express调试网站的方法
如果不想安装IIS,可以直接使用IIS Express来运行网站. vs2012: 新建个文档,拷贝下面代码 taskkill /F /IM "WebDev.WebServer40.EXE& ...