DP 水题
Permutation
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
Permutation plays a very important role in Combinatorics.
For example, 1 2 3 4 5 and 1 3 5 4 2 are both 5-permutations.
As everyone's known, the number of n-permutations is n!.
According to their magnitude relatives, if we insert the symbols '<' or '>' between every pairs of consecutive numbers of a permutation, we can get the permutation with symbols.
For example, 1 2 3 4 5 can be changed to 1<2<3<4<5,
1 3 5 4 2 can be changed to 1<3<5>4>2.
Now it's your task to calculate the number of n-permutations with k '<' symbols.
Maybe you don't like large numbers, so you should just give the result mod 2007.
Input
Input may contain multiple test cases.
Each test case is a line contains two integers n and k.0<n<=100 and 0<=k<=100.
The input will terminated by EOF.
Output
The nonnegative integer result mod 2007 on a line.
Sample Input
5 2
Sample Output
66
当前状态:dp[i][j]表示i个小于号,j个数字
可以转移到当前状态的有:dp[i][j-1]*(1+i)+dp[i-1][j-1]*(j-i)
初始: dp[0][i]=1;
1<2<4>3
再加一个数字5时,5可以插入的位置有4种:最左 最右 < >
插入后对 < 的影响:
最左 : 不变
最右 : +1
< : ....
> : ....
然后统计下有多少个<>~~
分析够彻底了。供我们这些小菜鸟参考应该还行~~
这题水分还是足够分量的。
if(j>=i)
dp[i][j]=dp[i][j-1]*(1+i)+dp[i-1][j-1]*(j-i);
if(dp[i][j]>=2007) 因为%的复杂度高,所以不放在上面。。当然也是个人习惯
dp[i][j]=dp[i][j]%2007;
//cout<<"1 "<<dp[i][j]<<endl; 可以观察每一步怎么走的。。
#include<cstdio> int dp[200][200]; //[i][j]表示i个小于号,j个数字 int n,k; int main() { while(scanf ("%d%d",&n,&k)!=EOF){ for(int i=0;i<=n;++i) dp[0][i]=1; for(int j=1;j<=n;++j) for(int i=1;i<=k;++i) { if(j>=i) dp[i][j]=dp[i][j-1]*(1+i)+dp[i-1][j-1]*(j-i); if(dp[i][j]>=2007) dp[i][j]=dp[i][j]%2007; //cout<<"1 "<<dp[i][j]<<endl; } printf("%d ",dp[k][n]); } return 0; }