Longest Increasing Subsequence Arrays (组合计数)
2016-07-25 13:21
417 查看
题目:
LINK题意:一个序列长度为 M, 每个数值在 [1, N], 问这个序列的最长上升子序列刚好
为N 的时候, 序列有多少种。
分析:
感谢kg2006的思路。首先选取 N 个位置 S1,S2,S3 ….. SN。 设S1 之前的位置没有 1, S1 - S2 没有 2…
则有 S1 之前 S1-S2之间 … SN-1 - SN 之间的数都是有 N-1 中选择方案。 而 SN
之后位置均为 N种。 枚举 SN 的位置 Last, 可以知道
Ans = ∑(Last−1N−1)∗(N−1)Last−N∗NM−Last
Code:
#include <iostream> #include <cstdio> using namespace std; typedef long long LL; typedef unsigned long long ULL; const int maxm = 500000 + 131; const int maxn = 100000 + 131; const LL MOD = 1e9 + 7; LL Mjie[maxm], Inv[maxm], JieInv[maxm]; LL PowN[maxm], PowN_[maxm]; void INIT() { Mjie[0] = Mjie[1] = 1; Inv[1] = 1; for(LL i = 2; i < maxm; ++i) { Mjie[i] = Mjie[i-1] * i % MOD; Inv[i] = (MOD - MOD / i) * Inv[MOD % i] % MOD; } JieInv[1] = JieInv[0] = 1; for(LL i = 2; i < maxm; ++i) JieInv[i] = JieInv[i-1] * Inv[i] % MOD; } int main() { INIT(); int t; LL m, n; scanf("%d", &t); while(t--) { scanf("%lld%lld", &m, &n); PowN_[0] = PowN[0] = 1; for(LL i = 1; i < maxm; ++i) { PowN[i] = PowN[i-1] * n % MOD; PowN_[i] = PowN_[i-1] * (n-1) % MOD; } LL Ans = 0; for(LL Last = m; Last >= n; Last--) { LL temp = (Mjie[Last-1] * JieInv[n-1] % MOD) * JieInv[Last-n] % MOD; temp = temp * PowN_[Last-n] % MOD; temp = temp * PowN[m-Last] % MOD; Ans =( Ans + temp ) % MOD; } printf("%lld\n", Ans); } }
相关文章推荐
- LEETCODE: Subsets II
- 组合排列、全排列 面试算法(5)
- 【Hacker Rank】03.Python If-Else
- 【Hacker Rank】02.Reading Raw Input
- 【Hacker Rank】01.Say "Hello, World!" With Python
- [Hackrank]Get Node Value
- 探索并优化组合算法的中的01移位转换法(非递归)
- C#实现组合排列的方法
- unique和unique_copy
- 用IntelliJ自动检查并生成serialVersionUID
- PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别
- Handler消息传递机制(一)理解到底为什么?
- UE4 UnrealEngine4 中 实现多通道技术
- IDE的一键Build背后隐藏了什么
- Fuison 360 API: 判断一个点是否在某曲面上
- [leetcode] 374. Guess Number Higher or Lower
- iOS--UITextField的简单使用
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- UIScrollViewDelegate Protocol Reference