lightoj 1095 - Arrange the Numbers (错排数)
2015-08-27 22:16
253 查看
题意:
求n个数的排列,前m个中有k个在自己的位置上的方法数。思路:
设D为n个元素的错排数.
于是我们有D[1] = 0 D[2] = 1;
D
= (D[n-1] + D[n-2]) * (i-1)
考虑问题本身,我们首先从前m个数选k个数不动.即C(m,k)。对于没有选的前m中的m-k个数肯定是参与了错排,而后面n-m个数中参加错排的个数不定,所以我们枚举一个后面n-m个数中选出i(0 <= i <= n - m)个数有没有参与错排。总共就有n-k-i参与了错排.
综上所述,ans公式就是C[m][k] * sigma(C[n-m][i] * D[n-k-i]) % mod;
预处理出组合数和错排数,然后就乱搞了。
注意有个坑点。。D[0]要赋值为1
参考code:
/* #pragma warning (disable: 4786) #pragma comment (linker, "/STACK:0x800000") */ #include <cassert> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <sstream> #include <iomanip> #include <string> #include <vector> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <algorithm> #include <iterator> #include <utility> using namespace std; template< class T > T _abs(T n){ return (n < 0 ? -n : n); } template< class T > T _max(T a, T b){ return (!(a < b) ? a : b); } template< class T > T _min(T a, T b){ return (a < b ? a : b); } template< class T > T sq(T x){ return x * x; } template< class T > T gcd(T a, T b){ return (b != 0 ? gcd<T>(b, a%b) : a); } template< class T > T lcm(T a, T b){ return (a / gcd<T>(a, b) * b); } template< class T > bool inside(T a, T b, T c){ return a<=b && b<=c; } #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define F(i, n) for(int (i)=0;(i)<(n);++(i)) #define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i)) #define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i)) #define repok(i, s, t, o) for(int (i)=(s);(i)<=(t) && (o);++(i)) #define MEM0(addr) memset((addr), 0, sizeof((addr))) #define MP(x, y) make_pair(x, y) #define REV(s, e) reverse(s, e) #define SET(p) memset(pair, -1, sizeof(p)) #define CLR(p) memset(p, 0, sizeof(p)) #define MEM(p, v) memset(p, v, sizeof(p)) #define CPY(d, s) memcpy(d, s, sizeof(s)) #define READ(f) freopen(f, "r", stdin) #define WRITE(f) freopen(f, "w", stdout) #define SZ(c) (int)c.size( #define PB(x) push_back(x) #define ff first #define ss second #define ll long long #define ld long double #define pii pair< int, int > #define psi pair< string, int > #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 #define debug(x) cout << #x << " = " << x << endl const double PI = acos(-1.0); const int inf = 1<<30; const int maxn = 1000; const int mod = 1000000007; int m,n,k; ll D[maxn+5]; ll C[maxn+5][maxn+5]; void init(){ C[0][0] = 1; rep(i,1,maxn){ C[i][0] = C[i][i] = 1; rep(j,1,i-1) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod; } D[1] = 0,D[0] = D[2] = 1; rep(i,3,maxn) D[i] = (i-1) * (D[i-1] + D[i-2]) % mod; } ll solve(int n,int m,int k){ ll ans = 0; rep(i,0,n-m) ans = (ans + C[n-m][i] * D[n-k-i]) % mod; return ans * C[m][k] % mod; } int main(){ //READ("in.txt"); int t,kase = 1; scanf("%d",&t); init(); while(t--){ scanf("%d%d%d",&n,&m,&k); printf("Case %d: %llu\n",kase++,solve(n,m,k)); } return 0; }
相关文章推荐
- 有关内存管理知识
- [leetcode-198]House Robber(java)
- 实现函数itob
- HTML5学习记录——3
- cp,mv,rm
- iPhone开发之UIScrollView滚动组件的使用(二) 拖线实现按钮控制大图移动利用contentOffset属性
- XML之PULL解析
- 排序算法小结(1) 插入排序
- HDU 1025
- 有关在敏捷测试中如何设计用例
- 软件生命周期—V模型
- 玩转UITableView
- sky简介
- 自定义函数与储存过程的区别
- VS C#多行预处理
- 【ztree系列】完美实现复选框功能
- centos6.5离线安装ftp服务
- poj3666 Making the Grade dp
- 有关翻页功能测用例设计
- 机器学习 libsvm交叉验证与网格搜索(参数选择)