CSU 1968 Permutation Descent Counts

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1968

题意:
对于任一种N的排列A,定义它的E值为序列中满足A[i]>A[i+1]的数的个数。给定N和K(K<=N<=1000),问N的排列中E值为K的个数。

 

思路:

这道题目和杭电的3664非常像。

d【i】【j】表示分析到i这个数时的E值为j的个数。

那么如何计算出d【i】【j】呢?得根据d【i-1】【j】和d【i-1】【j-1】递推出来。

①首先考虑d【i-1】【j】(此时不改变E值):

    1)、因为此时i是最大的,所以插在最后不改变E值,方法数为1

    2)、插入到每对逆序数中间,这样逆序数数量不会改变,方法数为j(因为一共有j对逆序对)

②然后是d【i-1】【j】(此时要让E值+1)

   1)、插入到最前面,E值+1,方法数为1

   2)、插入到不是逆序对中去,构成逆序对,E值+1,(i-1的数中一共有i-2对数,现在存在j-1对逆序对,那么i-2-j+1对数不是逆序对,可以插入到这几对数当中去),方法数为i-j+1

所以,最后的递推式就是

dp[i][j] = dp[i-1][j-1]*(i-j) + dp[i-1][j]*(j+1);
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 100 + 5;
17 
18 const int mod=1001113;
19 
20 int dp[200][200];
21 
22 void init()
23 {
24     for(int i=0;i<=100;i++)  dp[i][0]=1;
25     for(int i=2;i<=100;i++)
26     {
27         for(int j=1;j<i;j++){
28             dp[i][j]=(dp[i-1][j-1]*(i-j)+dp[i-1][j]*(j+1))%mod;
29         }
30     }
31 }
32 
33 int main()
34 {
35     int T;
36     int t,n,k;
37     init();
38     //freopen("in.txt","r",stdin);
39     scanf("%d",&T);
40     while(T--)
41     {
42         scanf("%d%d%d",&t,&n,&k);
43         printf("%d %d\n",t,dp[n][k]);
44 
45     }
46     return 0;
47 }

 

posted @ 2017-07-24 08:32  Kayden_Cheung  阅读(301)  评论(0编辑  收藏  举报
//目录