[关闭]
@ZCDHJ 2018-09-18T14:18:01.000000Z 字数 753 阅读 577

51Nod1020 逆序排列

动态规划 dp


51Nod

很明显的 DP 有木有

的全排列中有多少个逆序对数为

那么每次转移的时候只要枚举一下将新数插入到哪里就行(它会与其后面的所有数产生逆序对)。

但是这样子转移的话总复杂度是 的 直接gg。。。

的式子写出来,再相减就可以得到 。那么就可以 转移了。

其实也可以写前缀和优化的。。。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. const int MOD = 1e9 + 7;
  5. const int MAXN = 1000 + 5;
  6. const int MAXK = 20000 + 5;
  7. int T, N, K;
  8. int Dp[MAXN][MAXK];
  9. inline int read()
  10. {
  11. register int x = 0;
  12. register char ch = getchar();
  13. while(!isdigit(ch)) ch = getchar();
  14. while(isdigit(ch))
  15. {
  16. x = x * 10 + ch - '0';
  17. ch = getchar();
  18. }
  19. return x;
  20. }
  21. int main()
  22. {
  23. for(int i = 1; i <= 1000; ++i)
  24. {
  25. Dp[i][0] = 1;
  26. for(int j = 1; j <= std::min(20000, i * (i - 1) / 2); ++j)
  27. {
  28. Dp[i][j] = (Dp[i][j - 1] + Dp[i - 1][j]) % MOD;
  29. if(j >= i) (Dp[i][j] -= Dp[i - 1][j - i] - MOD) %= MOD;
  30. }
  31. }
  32. T = read();
  33. while(T--)
  34. {
  35. N = read();
  36. K = read();
  37. printf("%d\n", (Dp[N][K] + MOD) % MOD);
  38. }
  39. return 0;
  40. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注