博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 4899 Hero meet devil
阅读量:4560 次
发布时间:2019-06-08

本文共 1225 字,大约阅读时间需要 4 分钟。

传送阵:

题目大意:给定一个DNA序列,求有多少长度为m的序列与该序列的最长公共子序列长度为0,1...|S|;

分析:
我们可以考虑对于求两个串的最长公共子序列的dp:f[i,j]代表第一个串到了i,第二个串到了j的最长公共子序列。对于两个串来说,如果数组f[i]是完全一样的,则它们对后面的影响也是完全一样的,所以我们可以设2维状态:F[i,j]代表我们当前以及到了i,f[i]的状态为j的方案数,但是这样设状态第二维有10^10。我们发现一个f[i,j]一定不会比f[i,j-1]小,且最多比f[i,j-1]多1,所以我们在设状态的时候可以取个差值,就变成2^10了。

#include
#include
#include
#include
#include
using namespace std;#define maxn 20#define mod 1000000007char dic[]="ACTG";int add[1<<15][4];int dp[2][1<<15];int pre[maxn],lcs[maxn],ans[maxn];char s[maxn];int T,n,m;void Add(int &x,int y){ x+=y; if(x>=mod)x-=mod;}void init(){ scanf("%s",s+1);n=strlen(s+1); memset(add,0,sizeof(add)); memset(dp,0,sizeof(dp)); for(int state=0;state<(1<
>(i-1))&1); for(int k=0;k<4;++k){ for(int i=1;i<=n;++i) if(s[i]==dic[k])lcs[i]=pre[i-1]+1; else lcs[i]=max(lcs[i-1],pre[i]); int &t=add[state][k]; for(int i=1;i<=n;++i) t|=((lcs[i]!=lcs[i-1])<<(i-1)); } }}int get(int x){ int s=0; while(x){ s+=x&1; x>>=1; }return s;}void work(){ scanf("%d",&m); int *now=dp[0],*next=dp[1]; memset(next,0,(1<
View Code

 

转载于:https://www.cnblogs.com/117208-/p/5352693.html

你可能感兴趣的文章
Windows Server 2008 R2 备份与恢复详细实例
查看>>
Ubuntu上kubeadm安装Kubernetes集群
查看>>
关于java学习中的一些易错点(基础篇)
查看>>
MFC的多国语言界面的实现
查看>>
四则运算个人项目 最终版
查看>>
java线程系列---java5中的线程池
查看>>
SQL表连接
查看>>
新秀系列C/C++经典问题(四)
查看>>
memset函数具体说明
查看>>
经常使用的android弹出对话框
查看>>
确保新站自身站点设计的合理性的六大注意点
查看>>
1033. 旧键盘打字(20)
查看>>
The Zen of Python
查看>>
git安装及使用
查看>>
mysql一个非常实用解决sql查询优化的函数explain
查看>>
图文讲解NTFS和FAT32硬盘下 asp.net 生成word 错误: 80070005 和 错误:8000401a 的解决方法...
查看>>
《学习》5连接查询(高级查询)
查看>>
[BZOJ2730][HNOI2012]矿场搭建 点双 割点
查看>>
Linux/Mac 挂载远程服务器目录到本地
查看>>
1,实现在线答题 2,答题结束后可以判断对错 3,并将错题的结果保存起来。...
查看>>