洛谷 P1521 求逆序对
题目描述
我们说(i,j)是a1,a2,…,aN的一个逆序对当且仅当i<j且ai>a j。例如2,4,1,3,5的逆序对有3个,分别为(1,3),(2,3),(2,4)。现在已知N和K,求1…N的所有特定排列,这些排列的逆序对的数量恰好为K。输出这些特定排列的数量。
例如N=5,K=3的时候,满足条件的排列有15个,它们是:
1,2,5,4,3 1,3,4,5,2 1,3,5,2,4 1,4,2,5,3 1,4,3,2,5 1,5,2,3,4 2,1,4,5,3 2,1,5,3,4 2,3,1,5,4 2,3,4,1,5
2,4,1,3,5 3,1,2,5,4 3,1,4,2,5 3,2,1,4,5 4,1,2,3,5
输入输出格式
输入格式:
输入第一行有两个整数N和K。(N≤100,K≤N*(N-1)/2)
输出格式:
将1…N的逆序对数量为K的特定排列的数量输出。为了避免高精度计算,请将结果mod 10000以后再输出!
输入输出样例
输入样例#1:
5 3
输出样例#1:
0 1:1
1 2: 1,1
3 3:1,2, 2
6 4:1,3, 5, 6
10 5:1,4, 9, 15, 20, 22
15 6:1,5,14, 29, 49, 71, 90, 101, 101
21 7:1,6,20, 49, 98,169, 259, 359, 455, 531, 573, 573
28 8:1,7,27, 76,174,343, 602, 961,1415, 1940, 2493, 3017, 3450, 3736, 3836
36 9:1,8,35,111,285, 628,1230,2191,3606, 5545, 8031,11021,14395,17957,21450, 24584, 27073, 28675, 29228
150 0:1
先搜索。。。
ngs(k的最大值) n:f(k為0,1,2,3...)
0 1:1
1 2: 1,1
3 3:1,2, 2
6 4:1,3, 5, 6
10 5:1,4, 9, 15, 20, 22
15 6:1,5,14, 29, 49, 71, 90, 101, 101
21 7:1,6,20, 49, 98,169, 259, 359, 455, 531, 573, 573
28 8:1,7,27, 76,174,343, 602, 961,1415, 1940, 2493, 3017, 3450, 3736, 3836
36 9:1,8,35,111,285, 628,1230,2191,3606, 5545, 8031,11021,14395,17957,21450, 24584, 27073, 28675, 29228
45 10:1,9,44,155,440,1068,2298,4489,8095,13640,21670,32683,47043,64889,86054,110010,135853,162337,187959,211089,230131,243694,250749,250749
(註:應該是對稱的,為了不超行,我刪掉了後面的。)
看了一下上面的,相信聰明的,你,一定發現了規律。(呵呵,不可能的!)
if(j<=ngs[i]/2){
f[i][j]=f[i-1][j]+f[i][j-1];
if(j>=i) f[i][j]-=f[i-1][j-i];
}
else f[i][j]=f[i][ngs[i]-j];
呵呵,是不是很神奇。
因為數值很大,需要mod,這裡有一些小技巧。
代碼實現:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int mod=10000; 5 int n,k,ngs[120],f[120][6000]; 6 int main(){ 7 scanf("%d%d",&n,&k);f[0][0]=f[1][0]=1;//初始化。 8 for(int i=2;i<=n;i++){ 9 ngs[i]=ngs[i-1]+i-1;//你懂的。 10 for(int j=0;j<=ngs[i];j++){ 11 f[i-1][j]%=mod;//mod的小技巧。 12 if(j<=ngs[i]/2){//DP方程應用。 13 f[i][j]=f[i-1][j]+f[i][j-1]; 14 if(j>=i) f[i][j]-=f[i-1][j-i]; 15 } 16 else f[i][j]=f[i][ngs[i]-j]; 17 } 18 } 19 printf("%d\n",f[n][k]%mod);//mod的小技巧。 20 return 0; 21 }
這絕不是一道搜索題~