博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2019牛客暑期多校训练营(第一场)-E(DP)
阅读量:5093 次
发布时间:2019-06-13

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

题目链接:https://ac.nowcoder.com/acm/contest/881/E

题意:求可分解成n个AB和m个BA的字符串的个数。

思路:

  首先根据贪心思想,前n个A可作为AB的A,后m个A作为BA的A。可以证明,如果将前n个A中的一个作为BA的A,那一定可以从后面找到一个A来替代这个A。同理,前m个B作为BA的B,后n个B作为AB的B。

  如果不满足上面条件,一定不能满足n个AB和m个BA的要求。

  那么可以用dp来做,用dp[i][j]表示有i个A和j个B的前缀方案数。根据下一个选A还是选B可以得到dp[i+1][j]和dp[i][j+1],根据前面的条件有:

  如果i+1<=n,一定符合条件,直接转移,dp[i+1][j]=dp[i+1][j]+dp[i][j]。同理,如果j+1<=m,dp[i][j+1]=dp[i][j+1]+dp[i][j]。

  如果i+1>n,那么需要j>=i+1-n,dp[i+1][j]=dp[i+1][j]+dp[i][j]。同理,如果j+1>m,需要i>=j+1-m,dp[i][j+1]=dp[i][j+1]+dp[i][j]。

  这样合并即可,就得到了转移方程。

AC代码:

#include
using namespace std;const int MOD=1e9+7;const int maxn=1005;int dp[maxn<<1][maxn<<1];int n,m;int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=0;i<=n+m;++i) for(int j=0;j<=n+m;++j) dp[i][j]=0; dp[0][0]=1; for(int i=0;i<=n+m;++i) for(int j=0;j<=n+m;++j){ if(j>=i+1-n) dp[i+1][j]=(dp[i+1][j]+dp[i][j])%MOD; if(i>=j+1-m) dp[i][j+1]=(dp[i][j+1]+dp[i][j])%MOD; } printf("%d\n",dp[n+m][n+m]); } return 0;}

 

转载于:https://www.cnblogs.com/FrankChen831X/p/11215966.html

你可能感兴趣的文章
观察者模式
查看>>
(二十一)访问者模式-代码实现
查看>>
判断 wp 是否是活跃页面
查看>>
Unity3D界面功能操作讲解【转http://www.cnblogs.com/fortomorrow/archive/2012/10/28/unity01.html】...
查看>>
js编码问题
查看>>
iOS 25个性能优化/内存优化常用方法
查看>>
WCF中NetTCp配置
查看>>
Java自学之路(新手一定要看)
查看>>
数据库--MyBatis的(insert,update,delete)三种批量操作
查看>>
Python与Go插入排序
查看>>
冒泡排序
查看>>
sql server 2016新特性 查询存储(Query Store)的性能影响
查看>>
Dell T3610 台式工作站UEFI模式安装Win7系统
查看>>
NumPy 将停止支持 Python 2
查看>>
树莓派(raspberry pi)学习11: 将树莓派变成一个Web服务器(转)
查看>>
mysql-关联查询
查看>>
减少.NET应用程序内存占用的一则实践
查看>>
Java 数据结构之双链表
查看>>
[转]基于WorldWind平台的建筑信息模型在GIS中的应用
查看>>
php类的实现
查看>>