Description

统计 \(1...n\) 的排列,恰好进行 \(k\) 次相邻交换和至多进行 \(k\) 次交换生成的不同的序列个数.

Sol

DP.

好妙的题啊...

首先看第一个问题.

对于相邻元素的交换,我们建立状态 \(f[i][j]\) 表示前 \(i\) 个数进行 \(j\) 次交换的方案数.

我们分类来讨论 \(i\) 元素是否参与交换.

如果不参与交换 \(f[i][j]+=f[i-1][j]\)

如果参与交换,那么它最远能交换到的位置就是 \(i-j\) \(f[i][j]+=f[i-1][u],max\{ i-j,0 \}\leqslant u \leqslant j-1\)

其实合起来就是 \(f[i][j]=\sum_{u=max\{0,i-j\}} ^{j} f[i-1][u]\) ,前缀和搞一下就可以了.

然后第二个问题.

继续来分类讨论 \(i\) 元素是否参与交换.

如果不参与交换 \(f[i][j]+=f[i-1][j]\)

如果参与交换,那么它可以和前面任意一个元素交换 \(f[i][j]+=f[i-1][j-1]*(i-1)\)

非常简单啊...

至于最后的判重就更简单了,因为换两次可以换回来,那么就让 \(f[i][j]-f[i][j-2]\) 这才是 \(f[i][j]\) 真正的贡献.

PS:我好像卡常卡到第一了...

Code

#include<cstdio>
#include<iostream>
using namespace std; typedef long long LL;
const int N = 3005;
const LL p = 1000000007;
#define debug(a) cout<<#a<<"="<<a<<" " int n,k;
LL f[N][N]; int main(){
cin>>n>>k;
f[1][0]=1;
for(int i=0;i<=k;i++) f[2][i]=i+1;
for(int i=3;i<=n;i++) for(int j=0;j<=k;j++){
int l=j-min(j,i-1)-1;
f[i][j]=(f[i-1][j]-(l>=0?f[i-1][l]:0LL)+p)%p;
f[i][j]=(f[i][j]+f[i][j-1])%p;
}
//for(int i=1;i<=n;i++) for(int j=0;j<=k;j++) printf("%lld%c",f[i][j]," \n"[j==k]);
cout<<(f[n][k]-f[n][k-1]+p)%p<<" "; f[1][0]=1;
for(int i=0;i<=k;i++) f[2][i]=1;
for(int i=3;i<=n;i++) for(int j=0;j<=k;j++){
f[i][j]=f[i-1][j];
f[i][j]=(f[i][j]+f[i-1][j-1]*(i-1)%p)%p;
}
//for(int i=1;i<=n;i++) for(int j=0;j<=k;j++) printf("%lld%c",f[i][j]," \n"[j==k]);
LL ans=0;
for(int i=k;i>1;i--) ans=(ans+f[n][i]-f[n][i-2]+p)%p;
ans=(ans+f[n][0]+f[n][1])%p;
cout<<ans<<endl; return 0;
}

  

Code

51Nod 1250 排列与交换的更多相关文章

  1. 51nod 1250 排列与交换——dp

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 仔细思考dp. 第一问,考虑已知 i-1 个数有多少种方案. ...

  2. 51Nod 1250 排列与交换 —— DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 看了半天... 把第一问想成逆序对的话似乎很容易想了,新加入 ...

  3. php实现字符串的排列(交换)(递归考虑所有情况)

    php实现字符串的排列(交换)(递归考虑所有情况) 一.总结 交换: 当有abc的时候,分别拿第一位和其它位交换,第一位固定,余下的位做递归,这样有考虑到所有情况,因为第一位只可能是所有的字母,那第一 ...

  4. 51nod 1574 排列转换(贪心+鸽巢原理)

    题意:有两个长度为n的排列p和s.要求通过交换使得p变成s.交换 pi 和 pj 的代价是|i-j|.要求使用最少的代价让p变成s. 考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,p ...

  5. 51nod 1574 排列转换(猜结论)

    分析 猜了一下结论,居然对了..........具体操作是:假设排列s是1,2,3,...,nk为排列p中最大的 没有放到正确位置的数,k的位置为posk的右边一定有一个数x<=pos(因为&l ...

  6. 51nod 1843 排列合并机(DP+组合)

    题解链接 不过求ggg不用O(n2)DPO(n^2)DPO(n2)DP,g[n]g[n]g[n]直接就是卡特兰数的第n−1n-1n−1项.即: g[n]=(2(n−1)n−1)−(2(n−1)n−2) ...

  7. 对象的比较与排序:IComparable和IComparer接口

    IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: . ICompar ...

  8. UVa 11077 (循环分解 递推) Find the Permutations

    把{1, 2, 3,,, n}叫做自然排列 本题便是求有多少个n元排列P要至少经过k次交换才能变为自然排列. 首先将排列P看做置换,然后将其分解循环,对于每个长度为i的循环至少要交换i-1次才能归位. ...

  9. CF(441D Valera and Swaps)置换群

    题意:1-n的一个排列, p2, ..., pn,f(p)的定义是此排列要交换最少的数对能够回到原排列1,2,3,4...n.给一个排列p.要将其变换成f值为m的排列,问至少要交换几个数对,并输出字典 ...

随机推荐

  1. centos nc命令安装

    yum install nc.x86_64 nc命令的参数 参数 作用-i 设置数据报传送时间间隔-l 以服务器方式运行-k 重复接收并处理某个端口上的所有连接,必须与-l选项一起使用-n 使用ip地 ...

  2. 20145212 实验三《敏捷开发与XP实践》

    20145212 实验三<敏捷开发与XP实践> 实验内容 使用git上传代码 与20145223同学一组,使用git相互更改代码 同组实验报告链接:http://www.cnblogs.c ...

  3. ubuntu下安装wine1.8和阿里旺旺

    参考:http://www.linuxidc.com/Linux/2015-12/126722.htm和http://www.linuxidc.com/Linux/2016-05/131131.htm ...

  4. Tomcat的目录结构、处理流程、主配置文件(server.xml)释义

    参考资料: http://www.cnblogs.com/xdp-gacl/p/3744053.html http://grass51.blog.51cto.com/4356355/1123400 1 ...

  5. Java学习笔记2

    package welcome; public class Constants { public static void main(String[] args){ final double CM_PE ...

  6. MYSQL权限回收

    给予最小权限 grant '; FLUSH PRIVILEGES 查看全部用户:select * from mysql. user \G. 查看权限. mysql> show grants fo ...

  7. 在Centos上安装RabbitMQ流程(转)

    在Centos上安装RabbitMQ流程------------------------ 1. 需求 由于项目中要用到消息队列,经过ActiveMQ与RabbitMQ的比较,最终选择了RabbbitM ...

  8. mysql和oracle的区别(功能性能、选择、使用它们时的sql等对比)

    一.并发性 并发性是oltp数据库最重要的特性,但并发涉及到资源的获取.共享与锁定. mysql:mysql以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他se ...

  9. 【9-2】mysql数据库学习01

    mysql安装 下载社区版本MySQL软件包(地址),或者windows installer 接压缩安装包到目标路径 在系统变量Path中加入目标路径 在mysql安装路径下,修改配置文件mysql- ...

  10. 希望各位博友能对我的自我介绍提出意见(要面试IBM的应用开发工程师,本科应届生一枚)

    面试官你好,首先我非常高兴能参加今天的面试. 我叫XXX(我名字里面有光宗耀祖),也许父母希望我光宗耀祖吧,所以给我起这样的名字.我的家乡山西太原,本科就读于XX大学,专业是信息与计算科学. 我今天要 ...