好排列 题解
2016-07-28 15:53
393 查看
T<=10,0<=m<=n<=2000。
我们考虑这么思考,开始有长度为l-1的排列,现在我们在最后插入一个1~l的数,然后把数列中大于等于这个数的数全部加1,这样仍然是合法的。
这题想到这里就够了,我们就这样设计状态:dp[i][j]表示长度为i的排列按这种方法在最后插入了一个j,该加的加一之后的合法状态,就可以随便统计一下了。
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <string> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <sstream> #include <stack> #include <iomanip> #include <bitset> using namespace std; int T,n,m,ss[2333]; bool s[2333]; int dp[2003][2003]; int MOD=1000000007; void sol() { scanf("%d%d",&n,&m); memset(s,0,sizeof(s)); for(int i=1;i<=m;i++) scanf("%d",ss+i), s[ss[i]+1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=0; dp[1][1]=1; int ans=0; for(int i=2;i<=n;i++) { int sum=0; if(s[i]) { for(int j=1;j<=i;j++) { dp[i][j]=sum; sum=(sum+dp[i-1][j])%MOD; } } else { for(int j=i;j>=1;j--) { sum=(sum+dp[i-1][j])%MOD; dp[i][j]=sum; } } } for(int j=1;j<=n;j++) ans=(ans+dp [j])%MOD; printf("%d\n",ans); } int main() { freopen("good.in","r",stdin); freopen("good.out","w",stdout); scanf("%d",&T); while(T--) sol(); }
本来还有一道与排列有关的题...但是暂时找不到了就先不放了
相关文章推荐
- eclipse启动时虚拟机初始内存配置
- shell中export理解误区
- JS中级 - 01:DOM节点
- 分布式任务&分布式锁(li)
- filter()函数 条件筛选
- SCCI
- Android studio 预览报错解决
- CSAPP: Proxy lab
- markdown编辑器使用规则
- 不规则字符串转Date类型
- swift 基础语法
- 跨浏览器事件处理,能力检测:IE事件,DOM0级,DOM2级
- 镜头性能的裁判:MTF测试仪
- JS复制DOM元素文字内容
- excel to datatable (c#用NPOI将excel文件内容读取到datatable数据表中)
- 时区管理
- 英文缩写01
- jdbc的介绍
- POJ 1001 求高精度幂
- 跳槽指南