51Nod 1250 排列与交换
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 排列与交换的更多相关文章
- 51nod 1250 排列与交换——dp
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 仔细思考dp. 第一问,考虑已知 i-1 个数有多少种方案. ...
- 51Nod 1250 排列与交换 —— DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 看了半天... 把第一问想成逆序对的话似乎很容易想了,新加入 ...
- php实现字符串的排列(交换)(递归考虑所有情况)
php实现字符串的排列(交换)(递归考虑所有情况) 一.总结 交换: 当有abc的时候,分别拿第一位和其它位交换,第一位固定,余下的位做递归,这样有考虑到所有情况,因为第一位只可能是所有的字母,那第一 ...
- 51nod 1574 排列转换(贪心+鸽巢原理)
题意:有两个长度为n的排列p和s.要求通过交换使得p变成s.交换 pi 和 pj 的代价是|i-j|.要求使用最少的代价让p变成s. 考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,p ...
- 51nod 1574 排列转换(猜结论)
分析 猜了一下结论,居然对了..........具体操作是:假设排列s是1,2,3,...,nk为排列p中最大的 没有放到正确位置的数,k的位置为posk的右边一定有一个数x<=pos(因为&l ...
- 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) ...
- 对象的比较与排序:IComparable和IComparer接口
IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: . ICompar ...
- UVa 11077 (循环分解 递推) Find the Permutations
把{1, 2, 3,,, n}叫做自然排列 本题便是求有多少个n元排列P要至少经过k次交换才能变为自然排列. 首先将排列P看做置换,然后将其分解循环,对于每个长度为i的循环至少要交换i-1次才能归位. ...
- CF(441D Valera and Swaps)置换群
题意:1-n的一个排列, p2, ..., pn,f(p)的定义是此排列要交换最少的数对能够回到原排列1,2,3,4...n.给一个排列p.要将其变换成f值为m的排列,问至少要交换几个数对,并输出字典 ...
随机推荐
- 9月13日JavaScript语句循环(100以备奇偶数、100以内与7先关的数、100以内整数的和、10以内阶乘、乘法口诀、篮球弹起高度、64格子放东西)
3.循环 循环是操作某一个功能(执行某段代码). ①循环四要素: a 循环初始值 b 循环的条件 c 循环状态 d 循环体 ②for循环 a 穷举:把所有的可能性的都一一列出来. b 迭代:每次循环都 ...
- Java对象的多态性(转型)
多态性在面向对象中主要有两种体现: <1>方法的重载与覆写 <2>对象的多态性 对象的多态性:向上转型:子类对象-->父类对象,向上转型会自动完成 向下转型:父类对象-- ...
- debian vmwareTools安装总结
1.安装GCC编译器和make: 因为安装VMwareTools需要编译和make所以要先安装它们.安装其实很简单,命令如下: apt-get install gcc make 其实你也可以 ...
- 服务器后台TCP连接存活问题
0. 背景 公司的服务器后台部署在某一个地方,接入的是用户的APP,而该地方的网络信号较差,导致了服务器后台在运行一段时间后用户无法接入,那边的同事反馈使用netstat查看系统,存在较多的TCP连接 ...
- Nginx配置优化的几个参数
worker_processes 8 一般CPU(i/o)密集型配置为核数相同,网络(i/o)密集型配置为核数倍数(我配置为2倍) worker_cpu_affinity(这个没用过) 仅适用于lin ...
- [Unity] Unity3D研究院编辑器之自定义默认资源的Inspector面板
比如编辑模式下对场景或者特定文件夹有一些操作可以在这个面板里来完成.. 代码如下. using UnityEngine; using System.Collections; using UnityEd ...
- sqlserver权限体系(下)
简介 在上一篇文章中,我对主体的概念做了全面的阐述.本篇文章接着讲述主体所作用的安全对象以及所对应的权限. 理解安全对象(Securable) 安全对象,是SQL Server 数据库引擎授权系统控制 ...
- jsp的标签
一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...
- 在yii2验证之前执行一些额外自定义验证
<?php $form = ActiveForm::begin([ 'id' => $model->formName(), 'action' => ['/apitools/de ...
- python快排算法
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. ...