Pro
排列n个不同的数成为长度为p的序列每两个相同的数之间至少要隔着m个数
求排列总方案数
Input
三个整数 n,m,p
output
输出一个数字表示序列组成方法,由于结果可能很大,只需输出结果模上1000000007就可以啦
Sample Input 2 1 4
Sample Output 2
Data Range
20% N ≤ M ≤ 100
对于 100% 的数据,有 1 ≤ N ≤ P ≤ 1000,0 ≤ M ≤ N
正解:
DP 很多像这种求方案数的题目都是DP做的???
f[i][j]:序列的前i项里放了j种数的方案数
则在放第i+1个数时有两个选择:
1. 放一个新的数 则状态转移到f[i+1][j+1]
2. 放一个之前放过的数 则状态转移到f[i+1][j]
#include<iostream> #include<cstdio> #define ll long long #define go(i,a,b) for(register int i=a;i<=b;i++) #define mod 1000000007 using namespace std; int read() { int x=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x; } int n,m,p; ll f[1010][1010]; int main() { n=read();m=read();p=read(); f[0][0]=1; go(i,0,p) go(j,0,n) { f[i+1][j+1]=f[i][j]*(n-j)%mod; if(j>m) f[i+1][j]=(f[i][j]*(j-m)%mod+f[i+1][j])%mod; } printf("%lld",f[p][n]); return 0; }