http://acm.hdu.edu.cn/showproblem.php?pid=2583
题意: 输入 n m 问n组成的全排列中 有m个小于号的排列的个数
思路:
我们设
n(<=100)个数 1,2,...,n的排列有n!个 ,有k个小于号的有 f[n][k]个。
假如
a[1],a[2],...,a[n-1],是n-1个数的排列,有 k个‘<‘
把 n插入,有n个位置可以插入,
把 n插入到a[1]的前面, ‘<‘没有增加 , 1个位置
如 a[i]<a[i+1], 把 n插入到a[i+1]的前面, ‘<‘没有增加 , k个位置
插入到其他位置 ‘<‘增加
因此
f[n][k]=f[n-1][k]*(k+1) + f[n-1][k-1] *(n-k)
这个状态转移方程的初始状态:dp[n][0] = dp[n][n-1] = 1,因为分别只有为严格递增和严格递减一种情况。
#include<cstdio> #define N 101 #define inf 2007 int dp[N][N]; int main() { int n,k,i,j; for(i=0;i<N;i++) { dp[i][0]=1; dp[0][i]=0; } for(i=1;i<N;i++) for(j=1;j<N;j++) dp[i][j]=(dp[i-1][j]*(j+1)+dp[i-1][j-1]*(i-j))%inf; while(scanf("%d%d",&n,&k)!=EOF) { printf("%d\n",dp[n][k]); } return 0; }
原文地址:http://blog.csdn.net/u012773338/article/details/38850463