BZOJ2431 [HAOI2009]逆序对数列
Description
对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数。若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数。那么逆序对数为k的这样自然数数列到底有多少个?
Input
第一行为两个整数n,k。
Output
写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果。
Sample Input
样例输入
4 1
4 1
Sample Output
样例输出
3
样例说明:
下列3个数列逆序对数都为1;分别是1 2 4 3 ;1 3 2 4 ;2 1 3 4;
测试数据范围
30%的数据 n<=12
100%的数据 n<=1000,k<=1000
3
样例说明:
下列3个数列逆序对数都为1;分别是1 2 4 3 ;1 3 2 4 ;2 1 3 4;
测试数据范围
30%的数据 n<=12
100%的数据 n<=1000,k<=1000
正解:DP(递推)
解题报告:
这道题我居然没能一眼秒。。。
令f[i][j]表示前i个数逆序对数为j的序列个数,考虑DP(递推)。因为插入前i-1个数的时候方案已经得出了,我们需要插入第i个数获得新的一些序列。
因为i比前面任何一个数都要大,所以插在第几位,就会比后面的数大,对于总逆序对产生贡献。考虑贡献大小,可以插在前i-1个数的最后面,那么对于逆序对数没有产生任何贡献,所以就是从f[i-1][j]转移过来,但是插在其他位置呢?如果插在i-2个数后面就是产生1的贡献,所以是f[i-1][j-1]。。。最后i-1中总共i-1个数,所以新产生的贡献最大为i-1。可以得到方程式:f[i][j]=∑f[i-1][j-k](0<=k<i)
复杂度O(N^3)但是可以优化。因为每次用的是一段,所以前缀和优化一下,没必要每次重新统计。
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 1011; 21 const int MOD = 10000; 22 int n,k; 23 int f[MAXN][MAXN];//f[i][j]表示前i个数逆序对为j个的序列数 24 25 inline int getint() 26 { 27 int w=0,q=0; 28 char c=getchar(); 29 while((c<'0' || c>'9') && c!='-') c=getchar(); 30 if (c=='-') q=1, c=getchar(); 31 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 32 return q ? -w : w; 33 } 34 35 inline void work(){ 36 n=getint(); k=getint(); 37 f[0][0]=1; for(int i=1;i<=n;i++) f[i][0]=1; 38 int now=0; 39 for(int i=1;i<=n;i++) {//新加入的i可以插在之前的i-1个数中的任意位置,就会产生对逆序对数不同的贡献,可能贡献为0但最多为i-1。所以能加入当前的范围为j-i+1到j 40 now=f[i-1][0]; 41 for(int j=1;j<=k;j++){ 42 if(j-i>=0) now-=f[i-1][j-i]; 43 now+=f[i-1][j]; 44 f[i][j]+=now; 45 f[i][j]+=MOD; if(f[i][j]>=MOD) f[i][j]%=MOD; 46 } 47 } 48 printf("%d",f[n][k]); 49 } 50 51 int main() 52 { 53 work(); 54 return 0; 55 }
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!