HDU 3664 Permutation Counting(DP)

题目链接

弱爆啦,组合弱爆了,反正是没想出来怎么搞这个题,其实这个公式不难推啊,反正就是没推出来。今天队内赛,实在是没办法了,暴力写了个DFS,先把10以内的打出表来,发现类似杨辉三角的一个表,推不出公式,只能找规律了。也推公式,也找规律,中间还走会了神,发现borad上过的人N多了,有些着急,这样应该不难吧。。。又推了会,还是没想出来,找规律吧,估摸着应该是和上两项有关系,自己写了小程序测试一下几个数据和scf讨论了下,貌似真的是找出规律了。。。然后时间不多了,好在代码很短,马上快结束了,乱写了,最后在各种乱搞+思考之下,和暴力的写的数据对上了,中间错了2次,好在在4:53的时候终于AC了。。。。

公式的意义:p[i][j] = (i-j)*p[i-1][j-1] + (j+1)*p[i-1][j];对最后一个数进行讨论,最后一个数字,如果和a[i] > i的位置交换,最后一个数一定比那个位置大,所以之前就必须有j个a[i] > i的数,所以方案数为(j+1)*p[i-1][j] +1代表最后一个数的位置,如果最后一个数和a[i] < i的位置交换共有(i-1) - (j-1)个 ,则方案数为(i-j)*p[i-1][j-1]。

 1 #include <cstdio>

 2 #include <cstring>

 3 using namespace std;

 4 #define MOD 1000000007

 5 __int64 p[1001][1001];

 6 int main()

 7 {

 8     int i,j,n,k;

 9     for(i = 1;i <= 1000;i ++)

10     {

11         p[i][0] = 1;

12         p[i][i-1] = 1;

13     }

14     for(i = 3;i <= 1000;i ++)

15     {

16         for(j = 1;j <= (i+1)/2-1;j ++)

17         {

18              p[i][i-1-j] = p[i][j] = (((i-j)*p[i-1][j-1])%MOD+((j+1)*p[i-1][j])%MOD)%MOD;

19         }

20     }

21     while(scanf("%d%d",&n,&k)!=EOF)

22     {

23         printf("%I64d\n",p[n][k]);

24     }

25     return 0;

26 }

你可能感兴趣的:(count)