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:

  1. #include<cstdio>
  2. int f[][],mod=;
  3. int main()
  4. {
  5. freopen("B.in","r",stdin);
  6. freopen("B.out","w",stdout);
  7. char c;int i=,ans=;
  8. c=getchar();f[][]=;
  9. while(c=='D'||c=='I'||c=='?')
  10. {
  11. i++;
  12. for(int j=;j<i;j++)
  13. f[i-][j]=(f[i-][j]+f[i-][j-])%mod;
  14. if(c=='I'){
  15. for(int j=;j<=i;j++)
  16. f[i][j]=f[i-][j-];
  17. }
  18. if(c=='D'){
  19. for(int j=;j<i;j++)
  20. f[i][j]=(f[i-][i-]-f[i-][j-]+mod)%mod;
  21. }
  22. if(c=='?'){
  23. for(int j=;j<i;j++)
  24. f[i][j]=(f[i-][i-]-f[i-][j-]+mod)%mod;
  25. for(int j=;j<=i;j++)
  26. f[i][j]=(f[i-][j-]+f[i][j])%mod;
  27. }
  28. c=getchar();
  29. }
  30. for(int j=;j<=i;j++)
  31. ans=(ans+f[i][j])%mod;
  32. printf("%d",ans);return ;
  33. }

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:

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define ll long long
  7. #define inf 2147483647
  8. #define N 1005
  9. #define mod 1000000007
  10. using namespace std;
  11. int lcs[N][N],dp[N][N],ls[N][];
  12. char a[N],b[N];
  13. void lalala(){
  14. int la=strlen(a+),lb=strlen(b+);
  15. for(int i=;i<=la;i++)
  16. for(int j=;j<=lb;j++){
  17. if(a[i]==b[j])lcs[i][j]=lcs[i-][j-]+;
  18. else lcs[i][j]=max(lcs[i][j-],lcs[i-][j]);
  19. }
  20. }
  21.  
  22. void nanana(){
  23. int lb=strlen(b+);
  24. for(int i=;i<=lb;i++){
  25. memcpy(ls[i],ls[i-],sizeof(ls[i-]));
  26. ls[i][b[i]-'a'+]=i;
  27. }
  28. }
  29.  
  30. int aaa(){
  31. int la=strlen(a+),lb=strlen(b+);
  32. for(int i=;i<=la;i++)dp[i][]=;
  33. for(int j=;j<=lb;j++)dp[][j]=;
  34. for(int i=;i<=la;i++)
  35. for(int j=;j<=lb;j++){
  36. if(lcs[i-][j]==lcs[i][j]){
  37. dp[i][j]+=dp[i-][j];
  38. dp[i][j]%=mod;
  39. }
  40. int p=ls[j][a[i]-'a'+];
  41. if(lcs[i][j]==lcs[i-][p-]+&&p){
  42. dp[i][j]+=dp[i-][p-];
  43. dp[i][j]%=mod;
  44. }
  45. }
  46. return dp[la][lb];
  47. }
  48.  
  49. int main(){
  50. freopen("C.in","r",stdin);
  51. freopen("C.out","w",stdout);
  52. scanf("%s",a+);
  53. scanf("%s",b+);
  54. lalala();
  55. nanana();
  56. printf("%d",aaa());
  57. return ;
  58. }

    

两道很好的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. 自主学习之RxSwift(二) -----flatMap

    最近项目中有这么一个需求,下面是三个网络请求 A.从服务器获取到时间戳(GET 方法,获取 timeLine) B.进行用户头像上传,获得回传的URL(POST方法,参数为 userId, timeL ...

  2. jq 滚轮监听事件

    windowAddMouseWheel(); function windowAddMouseWheel() { var i = 0; var scrollFunc = function (e) { e ...

  3. ssh整合之七注解结合xml形式

    1.我们之前的纯xml的方式,我们的配置文件很多,我们可以使用注解结合xml的方式进行开发,这样的话,我们的配置文件,会少很多,同时,我们可以直接在类中看到配置,这样,我们就可以快速地搭建一个ssh整 ...

  4. 证明二叉查找树所有节点的平均深度为O(logN)

    数据结构与算法分析(c语言描述)第4章 P78 概念一:一棵树所有节点的深度和称为内部路径长 令D(N)为一棵有N节点的树的内部路径长么,即有D(1)=0, 设一棵树的左子树的内部路径长为D(i),则 ...

  5. python中导入模块的本质, 无法导入手写模块的解决办法

    最近身边一些朋友发生在项目当中编写自己模块,导入的时候无法导入的问题. 下面我来分享一下关于python中导入模块的一些基本知识. 1 导入模块时寻找路径 在每一个运行的python程序当中,都维护了 ...

  6. nexus私服服务器意外关机后,本地不能下载jar包

    主要记录一个小问题. 今天要做个需求,需要读取word文档中的表格来在生成数据库建表语句. 读取word文档,要添加maven依赖 <dependency> <groupId> ...

  7. python——常用模块2

    python--常用模块2 1 logging模块 1.1 函数式简单配置 import logging logging.debug("debug message") loggin ...

  8. 从零开始搭建springboot+mybatis+thymeleaf增删改查示例

    环境说明: 开发工具:Eclipse Mars.2 Release(4.5.2) JDK:1.8 Maven:3.3.3 注:Eclipse需安装sts插件,安装方法请自行百度 1. 新建maven工 ...

  9. NGUI---使用脚本控制聊天系统的内容显示,输入事件交互

    在我的笔记Unity3D里面之 简单聊天系统一 里面已经介绍怎么创建聊天系统的背景.给聊天系统添加滚动条,设置Anchor锚点.以及设计聊天系统的输入框. 效果图如下所示: 现在我们要做的就是使用脚本 ...

  10. jQuery系列 第四章 jQuery框架的选择器

    第四章 jQuery框架的选择器 4.1 jQuery选择器说明 jQuery 最核心的组成部分就是选择器引擎.它完全继承了 CSS 的风格,可以对 DOM 元 素的标签名.属性名.状态等进行快速准确 ...