题目描述

给出 \(n\) 个数 \(a_i\)​ ,以及 \(n\) 个数 \(b_i\)​ ,要求两两配对使得 \(a>b\) 的对数减去 \(a<b\) 的对数等于 \(k\) 。

\(0≤k≤n≤2000\),保证 \(a,b\) 无相同元素。

题解

我们假设 \(a>b\) 对数为 \(x\) ,可以求得 \(x=\frac{n+k}{2}\) 。

先对两个数组都排序

设\(pos[i]\)表示最大的\(j\)使得\(a_i>b_j\)

我们令 \(f_{i,j}\)​ 表示前 \(i\) 个 \(a\) 中,选了 \(j\) 组满足 \(a>b\) 的方案数。(注意不是前i个\(b\))

\(f_{i,j}\) = \(f_{i-1, j-1} + f_{i-1, j-1} * (pos[i]-j+1)\)

然而,这样弄完后,我们会发现会发现计算中的方案可以选多余\(j\)组,这样就会算重复许多方案

考虑如何去重

设\(g[i]\)表示前i个a,恰好选了\(j\)组

\(g[i]=f[n][i]∗(n−i)!−∑g[j] * C_j^i, (i<j≤n)\)

因为不知道a里面剩下的\(n-i\)个数是怎么匹配的,但是一定有\((n−i)!\)种匹配情况,这些情况里包含了恰好有j组a大于b的情况\((i<j)\),j组被计算到的次数是 \(C_j^i\) 种,所以减去,\(g[m]\)即是答案

Code

#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std; inline int gi() {
int f = 1, s = 0;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -1, c = getchar();
while (c >= '0' && c <= '9') s = s*10+c-'0', c = getchar();
return f == 1 ? s : -s;
}
const int N = 2010, Mod = 1e9+9;
int a[N], b[N], pos[N];
LL jc[N], C[N][N], f[N][N], g[N];
int main() {
int n = gi(), m = gi();
if ((n+m)&1) {
printf("0\n");
return 0;
}
m = (n+m)>>1;
for (int i = 1; i <= n; i++) a[i] = gi();
for (int i = 1; i <= n; i++) b[i] = gi();
sort(a+1, a+1+n); sort(b+1, b+1+n);
for (int i = 1; i <= n; i++) {
int p = 0;
while (p < n && b[p+1] < a[i]) p++;
pos[i] = p;
}
for (int i = 0; i <= n; i++)
C[i][0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % Mod;
jc[0] = jc[1] = 1;
for (int i = 2; i <= n; i++)
jc[i] = jc[i-1]*i%Mod; f[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= i; j++) {
if (pos[i] >= j)
f[i][j] = (f[i-1][j] + f[i-1][j-1]*(pos[i]-j+1))%Mod;
}
}
for (int i = n; i >= m; i--) {
g[i] = f[n][i]*jc[n-i];
for (int j = i+1; j <= n; j++)
g[i] = (g[i]-g[j]*C[j][i]%Mod+Mod)%Mod;
}
printf("%lld\n", g[m]);
return 0;
}

最新文章

  1. SpringSecurity操作指南-在SpringMVC项目上配置Spring Security
  2. C#编程总结(十四)dynamic
  3. Python多线程开发简介
  4. Java并发编程中的阻塞和中断
  5. ionic实现手机检测app是否安装,未安装则下载安装包,已安装则打开app(未实现iOS平台)
  6. [Effective C++ --020]宁以pass-by-reference-to-const替换pass-by-value
  7. 移动端触摸滑动插件Swiper
  8. 密码输入模块getpass
  9. lvs、haproxy、nginx 负载均衡的比较分析
  10. VSTO学习笔记(一)VSTO概述
  11. Floodlight Controller 路线原则
  12. MD5 .net与PHP加密值一样的加密代码
  13. 点击按钮颜色变深.通过ColorFilter ColorMatrix
  14. 20172328《程序设计与数据结构》实验三 敏捷开发与XP实践报告
  15. 对C#中的Close()和Dispose()的浅析
  16. 请求转发(forward)和请求重定向(redirect)的区别(转)
  17. Practice2 结对子之“小学四则运算”
  18. springboot(七)邮件服务
  19. 函数使用十二:BAPI_MATERIAL_BOM_GROUP_CREATE(CS61)
  20. U3D组件------CharacterController(角色控制器)

热门文章

  1. iframe 模拟ajax文件上传and formdata ajax 文件上传
  2. Docker01 centos系统安装、centos安装docker、docker安装mongoDB
  3. PCL点云库中的坐标系(CoordinateSystem)
  4. c语言实战 逆序一个三位数
  5. Linux Valgrind命令
  6. 用JQuery获取输入框中的光标位置
  7. Storm的wordCounter计数器详解
  8. OM—&gt;AR相关会计科目
  9. 自己总结的,输出到前端JSON的几种方法
  10. php 递归删除目录