A

  问题描述:

  对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用I表示,反之这个位置是下降的,用D表示。如排列3,1,2,7,4,6,5可以表示为DIIDID。

  现在给出一个长度为n-1的排列表示,问有多少种1到n的排列满足这种表示。

  输入:

  一个字符串S,S由I,D,?组成.?表示这个位置既可以为I,又可以为D。

  输出:

  有多少种排列满足上述字符串。输出排列数模1000000007

  样例输入:

  ?D

  样例输出:

  3

  数据范围:

  20%的数据 S长度<=10

  100%的数据 S长度<=1000

  分析:怎么做?先想一想,i+1个数的方法数可以用i个数的方法数推出来,自然就想到了dp。一看数据范围,1000,只可以开二维,多半是二维dp。

  dp[i][j] i表示共有i个数,j表示当前序列的最后一位为j。可以发现一个东西:前面i个数范围都在1~i且1~i中的每个数都只出现了1次。得出下列结论:

  1.'D' 呈下降趋势,当前这位填j,前面那位可以填j+1~i-1(i表示序列长度,已经+1),但这样的话,前面又有一个j,和当前这位j矛盾。我们可以视作前面所有>=j的数全部+1,来避免这种矛盾,所以当前位为j的前一位实际可以填j~i-1。(这一句重点)

  2.'I' 呈上升趋势,当前这位填j,前一位填1~j-1的数。为什么不能填j?因为当前位填j后实际上整个序列是少一个为i(i表示序列长度,已经+1)的数的,我们只能把每个>=j的数视作+1来避免这种bug。如果当前位填j,前一位填j,前面那位会被视作+1,矛盾。

  3.'?' D和I的情况加起来,耶。

  解决。

CODE:

 #include<cstdio>
int f[][],mod=;
int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
char c;int i=,ans=;
c=getchar();f[][]=;
while(c=='D'||c=='I'||c=='?')
{
i++;
for(int j=;j<i;j++)
f[i-][j]=(f[i-][j]+f[i-][j-])%mod;
if(c=='I'){
for(int j=;j<=i;j++)
f[i][j]=f[i-][j-];
}
if(c=='D'){
for(int j=;j<i;j++)
f[i][j]=(f[i-][i-]-f[i-][j-]+mod)%mod;
}
if(c=='?'){
for(int j=;j<i;j++)
f[i][j]=(f[i-][i-]-f[i-][j-]+mod)%mod;
for(int j=;j<=i;j++)
f[i][j]=(f[i-][j-]+f[i][j])%mod;
}
c=getchar();
}
for(int j=;j<=i;j++)
ans=(ans+f[i][j])%mod;
printf("%d",ans);return ;
}

B

  问题描述:

  小A非常喜欢字符串,所以小K送给了小A两个字符串作为礼物。两个字符串分别为X,Y。小A非常开心,但在开心之余她还想考考小K。小A定义L为X与Y的最长公共子序列的长度(子序列在字符串内不一定连续,一个长度为L的字符串有2^L个子序列,包括空子序列)。现在小A取出了X的所有长度为L的子序列,并要求小K回答在这些子序列中,有多少个是Y的子序列。因为答案可能很大,所以小K只需要回答最终答案模10^9 + 7。

  输入:

  第一行包含一个非空字符串X。

  第二行包含一个非空字符串Y。

  字符串由小写英文字母构成。

  输出:

  对于每组测试数据输出一个整数,表示对应的答案。

  样例输入:

  aa

  ab

  样例输出:

  2

  数据范围:

  对于20%的数据,1 <= |X|,|Y| <= 10

  对于100%的数据,1 <= |X|,|Y| <= 1000

  

  

  分析:一道很有趣的题,我没看出是dp

  题目必须读懂,虽说是求a中所有长度为L的序列在b中出现的个数,其实就是求最大长度的lcs有多少种方法。。。cnm坑比题。知道这一点之后,dp方程也就不难想了。

  由于范围是1000,所以只能开二维。dp[i][j]定义a中的前i个字符和b中的前j个字符构成的长度为 lcs(i,j)的公共子序列有多少种。

  肯定先求lcs,每个位置的lcs都要求。然后dp怎么转移呢?由于是在a中取序列,只考虑a中的某位置的字符取还是不取。

  1.如果不取当前这第i位的字符,且lcs[i][j]=lcs[i-1][j],说明啥?说明了a中i位置这个字符对答案并无贡献,所以只用继承就可以。dp[i][j]+=dp[i-1][j]

  2.取第i位字符。如果取了这个字符后,会有一个新的lcs长度刚好达到lcs[i][j],那么这个位置的方法数也是可以加过来的。那么我们怎么表示新lcs的结尾在b中对应的是哪个字符(设为x,其最后位置为p)?预处理一下每个字符在b中出现的最后位置。为什么非要p,万一前面的x也可以构成新lcs呢?贪心,后面方法数的肯定比前面的方法数多,取p方法数一定最优。dp[i][j]+=dp[i-1][p-1]

  PS:为什么这样做得到的一定是长度为lcs(a,b)的公共子序列,很有意思,lcs(a,b)中存的一定是最长lcs的长度,如果,只有长度满足才会递推过去,啊哈哈哈,啊哈哈哈。

  完美解决,耶!

CODE:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define inf 2147483647
#define N 1005
#define mod 1000000007
using namespace std;
int lcs[N][N],dp[N][N],ls[N][];
char a[N],b[N];
void lalala(){
int la=strlen(a+),lb=strlen(b+);
for(int i=;i<=la;i++)
for(int j=;j<=lb;j++){
if(a[i]==b[j])lcs[i][j]=lcs[i-][j-]+;
else lcs[i][j]=max(lcs[i][j-],lcs[i-][j]);
}
} void nanana(){
int lb=strlen(b+);
for(int i=;i<=lb;i++){
memcpy(ls[i],ls[i-],sizeof(ls[i-]));
ls[i][b[i]-'a'+]=i;
}
} int aaa(){
int la=strlen(a+),lb=strlen(b+);
for(int i=;i<=la;i++)dp[i][]=;
for(int j=;j<=lb;j++)dp[][j]=;
for(int i=;i<=la;i++)
for(int j=;j<=lb;j++){
if(lcs[i-][j]==lcs[i][j]){
dp[i][j]+=dp[i-][j];
dp[i][j]%=mod;
}
int p=ls[j][a[i]-'a'+];
if(lcs[i][j]==lcs[i-][p-]+&&p){
dp[i][j]+=dp[i-][p-];
dp[i][j]%=mod;
}
}
return dp[la][lb];
} int main(){
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
scanf("%s",a+);
scanf("%s",b+);
lalala();
nanana();
printf("%d",aaa());
return ;
}

    

两道很好的dp题目【4.29考试】的更多相关文章

  1. 两道NOIP里的DP题目~

    拦截导弹    来源:NOIP1999(提高组) 第一题 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都 ...

  2. 与高精死杠的几天——记两道简单的高精dp

    (同样也是noip往年的题 1​.矩阵取数游戏 题目链接[Luogu P1005 矩阵取数游戏] \(\mathcal{SOLUTION}:\) 通过对题目条件的分析,我们可以发现,每一行取数对答案的 ...

  3. leetcode简单题目两道(2)

    Problem Given an integer, write a function to determine if it is a power of three. Follow up: Could ...

  4. 『ACM C++』Virtual Judge | 两道基础题 - The Architect Omar && Malek and Summer Semester

    这几天一直在宿舍跑PY模型,学校的ACM寒假集训我也没去成,来学校的时候已经18号了,突然加进去也就上一天然后排位赛了,没学什么就去打怕是要被虐成渣,今天开学前一天,看到最后有一场大的排位赛,就上去试 ...

  5. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  6. 两道人数多,课程少,query多的题

    #每天进步一点点# 来两道很相似的题目~ (智商啊智商.....) hihoCoder #1236:Scores (简单的分桶法+bitset) 2015 Beijing Online的最后一题.题目 ...

  7. js 从两道面试题加深理解闭包与箭头函数中的this

     壹 ❀ 引 在本文之前我已经花了两个篇幅专门介绍了JavaScript中的闭包与this,正好今早地铁上看到了两道面试题,试着做了下发现挺有意思,所以想单独写一篇文章来记录解析过程.若你对于闭包与t ...

  8. FJOI2020 的两道组合计数题

    最近细品了 FJOI2020 的两道计数题,感觉抛开数据范围不清还卡常不谈里面的组合计数技巧还是挺不错的.由于这两道题都基于卡特兰数的拓展,所以我们把它们一并研究掉. 首先是 D1T3 ,先给出简要题 ...

  9. ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

    两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory ...

随机推荐

  1. Flask 学习 八 用户角色

    角色在数据库中表示 app/models.py class Role(db.Model): __tablename__='roles' id = db.Column(db.Integer,primar ...

  2. UWP 页面间传递参数(常见类型string、int以及自定义类型)

    这是一篇很基础的,大佬就不要看了,也不要喷,谢谢

  3. HDFS的7个设计特点

    1.Block的放置:默认不配置.一个Block会有三份备份,一份放在NameNode指定的DataNode,另一份放在与指定DataNode非同一Rack上的DataNode,最后一份放在与指定Da ...

  4. linux系统命令学习系列-用户切换命令su,sudo

    先复习一下上节内容: 用户组添加groupadd 用户组修改groupmod 用户组删除groupdel 作业创建一个id为501的组group1,然后改成group2, 同时id变为502,最后删除 ...

  5. 新概念英语(1-103)The French Test

    Lesson 103 The French test 法语考试 Listen to the tape then answer this question. How long did the exam ...

  6. 修改hosts 流畅使用coursera

    以管理员权限打开 C盘 ->  Windows-> System32 -> drives -> etc -> hosts文件 在hosts文件最后写入 52.84.246 ...

  7. python中 functools模块 闭包的两个好朋友partial偏函数和wraps包裹

    前一段时间学习了python当中的装饰器,主要利用了闭包的原理.后来呢,又见到了python当中的functools模块,里面有很多实用的功能.今天我想分享一下跟装饰器息息相关的两个函数partial ...

  8. WebStorm2018破解

    参考网站http://www.sdbeta.com/wg/2018/0302/220048.html修改整理如下: webstorm 2018.1正式版破解summary jetbrainscrack ...

  9. 从PRISM开始学WPF(九)交互Interaction?

    0x07交互 这是这个系列的最后一篇了,主要介绍了Prism中为我们提供几种弹窗交互的方式. Notification通知式 Prism通过InteractionRequest 来实现弹窗交互,它是一 ...

  10. scrapy-redis使用以及剖析

    scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能: scheduler - 调度器 dupefilter - URL去重 ...