【uoj149】 NOIP2015—子串
http://uoj.ac/problem/149 (题目链接)
题意
给出两个字符串A、B,问从A中取出k个互不重叠的子串按顺序组成B的方案数。
Solution
一看这种题目就是字符串dp,字符串dp的话套路都差不多。一开始我直接无脑${f[k][i][j]}$,表示从A串前缀${i}$中取出${k}$个子串组成B串前缀${j}$的方案数,但是这样做的话转移过来的状态有点多,不太好讨论。。于是我又开了一个${g}$数组来记录一种状态。
于是,${g[k][i][j]}$表示从A串前缀${i}$中取出${k}$个子串组成B串前缀${j}$的方案数,并且最后一个子串的最后一个字母是${A[i]}$。${f[k][i][j]}$表示从A串前缀${i}$中取出${k}$个子串组成B串前缀${j}$的方案数,并且最后一个子串的最后一个字母不是${A[i]}$。
那么转移就分两种情况:
1.当${a[i]=b[i]}$,那么:${g[k][i][j]=f[k-1][i-1][j-1]+g[k][i-1][j-1]+g[k-1][i-1][j-1]}$。
2.无论${a[i]}$是否等于${b[i]}$,${f[k][i][j]=f[k][i-1][j]+g[k][i-1][j]}$。
很好理解吧。然后发现第一维的${k}$只会与前面的${k-1}$有关,为了节省空间我就把它滚动了。
细节
滚动数组记得每次开始时清空。
代码
// uoj150
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define MOD 1000000007
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=1010;
LL f[2][maxn][210],g[2][maxn][210];
char a[maxn],b[maxn];
int n,m,K; int main() {
scanf("%d%d%d",&n,&m,&K);
scanf("%s",a+1);
scanf("%s",b+1);
int x=0;
for (int k=0;k<=K;k++)
for (int i=0;i<=n;i++) f[0][i][0]=f[1][i][0]=1;
for (int k=1;k<=K;k++) {
x^=1;
memset(f[x],0,sizeof(f[x]));memset(g[x],0,sizeof(g[x]));
for (int i=k;i<=n;i++)
for (int j=k;j<=min(i,m);j++) {
if (a[i]==b[j])
g[x][i][j]=(f[x^1][i-1][j-1]+g[x][i-1][j-1]+g[x^1][i-1][j-1])%MOD;
f[x][i][j]=(f[x][i-1][j]+g[x][i-1][j])%MOD;
}
}
printf("%lld",(f[x][n][m]+g[x][n][m])%MOD);
return 0;
}
【uoj149】 NOIP2015—子串的更多相关文章
- NOIP2015子串[序列DP]
题目背景 无 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重 叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个 ...
- LOJ2424 NOIP2015 子串 【DP】*
LOJ2424 NOIP2015 子串 LINK 题目大意是给你两个序列,在a序列中选出k段不重叠的子串组成b序列,问方案数 首先我们不考虑相邻的两段,把所有相邻段当成一段进行计算 然后设dpi,j, ...
- NOIP2015 子串
#149. [NOIP2015]子串 有两个仅包含小写英文字母的字符串 AA 和 BB. 现在要从字符串 AA 中取出 kk 个互不重叠的非空子串,然后把这 kk 个子串按照其在字符串 AA 中出现的 ...
- [NOIP2015] 子串(dp)
题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问 ...
- [vijos1982][NOIP2015]子串
Description 有两个仅包含小写英文字母的字符串和.现在要从字符串中取出个互不重叠的非空子串,然后把这个子串按照其在字符串中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这 ...
- [NOIP2015] 子串substring 题解
[题目描述] 有两个仅包含小写英文字母的字符串A和B.现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得 ...
- NOIP2015 子串 (DP+优化)
子串 (substring.cpp/c/pas) [问题描述] 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个 互不重 叠 的非空子串,然后把这 k 个子串按照其在字 ...
- [DP][NOIP2015]子串
子串 题目描述 有两个仅包含小写英文字母的字符串 A 和 B. 现在要从字符串 A 中取出 k 个 互不重叠 的非空子串, 然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的 ...
- [NOIP2015]子串 题解
题目描述 有两个仅包含小写英文字母的字符串A和B. 现在要从字符串A中取出k个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可 ...
随机推荐
- Meet python: little notes 4 - high-level characteristics
Source: http://www.liaoxuefeng.com/ ♥ Slice Obtaining elements within required range from list or tu ...
- 尝试HTML + JavaScript 编写Windows App
一直以来博文中使用最多的就是C# + XAML.进入Windows App时代,又多了一对 Javascript + HTML组合,这对于Web开发的程序员来说再熟悉不过了.其实小编也做过几年的Web ...
- Construct Binary Tree from Inorder and Postorder Traversal
Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of ...
- Memcached的安装和使用以及nginx整合memcached
一.模块的安装启动 wget http://cdnetworks-kr-2.d1.sourceforge.net/project/levent/libevent/libevent-2.0/libeve ...
- oracle:db-link使用
二个oracle instance,如果需要在一个instance上,直接查询另一个instance上的数据,就要用到db-link 创建: create public database link 链 ...
- python2.1-原理之琐碎技巧
本系列依据<python学习手册第四版>而写,也算是个学习笔记吧,选择本书的原因在于它不同于第三版,它强调介绍python3.0 ,而会在不同的地方给出2.6版本的区别,:本书侧重介绍原理 ...
- rsync实现负载均衡集群文件同步,搭建线上测试部署环境
闲来无事,搭建一个负载均衡集群,至于负载均衡集群搭建过程,找时间写下.这次主要写集群之间的文件同步,以及线上测试环境的搭建. 笔者看过很多公司都没有线上测试环境,真是崩溃了,不造怎么确保线上线下环境一 ...
- sockaddr与sockaddr_in结构体简介
struct sockaddr { unsigned short sa_family; /* address family, AF_xxx */char sa_data[14]; ...
- 用matlab实现同一个序列重复N倍
同一个序列 重复N倍 怎么用matlab实现 可以使用repmat函数 repmat(A, 1, 3) 其中A即为复制的矩阵,1为纵向复制的次数,3即为横向复制的次数.
- 链接错误-库冲突(libcmt.lib和libcmtd.lib)
在同一个项目中,所有的源文件必须链接相同的C运行时库.如果某一文件用了Multithreaded DLL版本,而其他文件用了Single-Threaded或者Multithreaded版本的库,也就是 ...