BZOJ 3622 已经没有什么好害怕的了 动态规划+容斥原理

题目大意:给定两个长度为n个序列,保证这2n个数字两两不同,求有多少匹配满足a[i]>b[i]的数对数比a[i]<b[i]的数对数多k

もう何も怖くない

题解:http://www.cnblogs.com/dyllalala/p/3900077.html

OTZ

神思路根本就是想不到啊QAQ

でも。。。もう何も怖くない。。。(大雾

此外我们可以引入一下WTY公式:

C[i][j]=C[i-1][j]*C[i-1][j-1]

。。。脑残怎么治啊。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 2020
#define MOD 1000000009
using namespace std;
int n,k,s;
int a[M],b[M],next[M];
long long C[M][M],fac[M];
long long f[M][M],g[M];
//f[i][j]表示前i个糖果中已经确定有j组糖>药的方案数
int main()
{
	int i,j;
	cin>>n>>k;
	if(n+k&1)
	{
		cout<<0<<endl;
		return 0;
	}
	s=n+k>>1;
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(i=1;i<=n;i++)
		scanf("%d",&b[i]);
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);

	for(j=1,i=1;i<=n;i++)
	{
		for(;j<=n&&b[j]<a[i];j++);
		next[i]=j-1;
	}

	f[0][0]=1;
	for(i=1;i<=n;i++)
	{
		f[i][0]=1;
		for(j=1;j<=i;j++)
			f[i][j]=(f[i-1][j]+f[i-1][j-1]*max(next[i]-(j-1),0))%MOD;
	}

	for(i=0;i<=n;i++)
	{
		C[i][0]=1;
		for(j=1;j<=i;j++)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
	}

	for(fac[0]=1,i=1;i<=n;i++)
		fac[i]=fac[i-1]*i%MOD;

	for(i=n;i>=s;i--)
	{
		g[i]=f[n][i]*fac[n-i]%MOD;
		for(j=i+1;j<=n;j++)
			(g[i]+=MOD-g[j]*C[j][i]%MOD)%=MOD;
	}

	cout<<g[s]<<endl;
	return 0;

}
时间: 2024-10-29 03:21:58

BZOJ 3622 已经没有什么好害怕的了 动态规划+容斥原理的相关文章

BZOJ 3622(已经没有什么好害怕的了-Dp+容斥原理)

3622: 已经没有什么好害怕的了 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 7  Solved: 6 [Submit][Status] Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output 4 HINT Source 2014湖北省队互测week2 PS:本题的数据中能量互不相同. 1.我们计算出糖果>药片的组数=k 2.我们计算出f[

[BZOJ 3622]已经没有什么好害怕的了

世萌萌王都拿到了,已经没有什么好害怕的了——    (作死) 笑看哪里都有学姐,真是不知说什么好喵~ 话说此题是不是输 0 能骗不少分啊,不然若学姐赢了,那么有头的学姐还能叫学姐吗?  (作大死) 这题的数据就告诉我们这是赤裸裸的 dp ,不过要加个容斥而已 注意到我们可以算出一共需要 s 组满足糖果数 > 药片数 (在这里显然有个特判,即 n-k 为奇数时,答案一定为 0 ) 我们将两个读入的数组排序 令 next[i] 表示最大的 j 满足 糖果[i]>药片[j] 令 f[i][j] 表示

[BZOJ 3622]已经没有什么好害怕的了(Dp+容斥原理)

Description 图片略 Solution 对啊,已经没有什么好害怕的了 没有头的麻美学姐还是很萌的(雾 排序预处理p[i]为b中小于a[i]的最大的数的标号 f[i][j]表示前i个糖果使得糖果大于药片的至少有j组 则f[i][j]=f[i-1][j]+f[i-1][j-1]*(p[i]-j+1) 容斥得g[j]=f[n][j]*(n-j)!-∑g[k]*C(j,k) (j+1<=k<=n) #include<iostream> #include<cstdio>

[BZOJ 3622] 已经没有什么好害怕的了 手动反演

题意 给定两个大小为 n 的集合 A = {a[1], a[2], ..., a[n]} , B = {b[1], b[2], ..., b[n]} , 元素两两不同. 定义 L(A) 为 A 生成的排列的集合. 给定 K , 求 $\sum_{X \in L(A), Y \in L(B)} [\sum_{k = 1} ^ n [X_k > Y_k] - \sum_{k = 1} ^ n [X_k < Y_k] = K]$ . 1 <= n <= 2000, 0 <= K &

【BZOJ3622】已经没有什么好害怕的了 动态规划+容斥原理

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44836095"); } 题解: 首先我们给A数组(糖果)和B数组(药片)从小到大排个序. lasti 表示一个极大值 x 使得 Bx<Ai . f(i,j) 表示枚举到第 Ai 时,有至少 j 对匹配,使得 A???>B

bzoj 3622 DP + 容斥

LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[i]大于b的组数. 不妨从整体去考虑,使用$f[n][j]$代表前n个中有j组$a[i]>b[i]$,很容易得到转移式$f[n][j]=f[n-1][j]+f[n-1][j-1]*(cnt[n]-(j-1))$,其中$cnt[i]$为比a[i]小的b[]个数 但是仔细思考该式子含义会发现,$f[n][j

【bzoj 3622】已经没有什么好害怕的了

题目 看到这个数据范围就发现我们需要一个\(O(n^2)\)的做法了,那大概率是\(dp\)了 看到恰好\(k\)个我们就知道这基本是个容斥了 首先解方程发现我们需要使得\(a>b\)的恰好有\(\frac{n+k}{2}\)组 如果不整除我们直接输出\(0\)就好了 之后开始使用套路,直接广义容斥 \[ans=\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}g_i\] \(g_i\)表配出至少\(i\)对\(a>b\)的情况 显然我们现在需要一个\(dp\)来算一下\(g

bzoj 3622

直接算 $a_i>b_i$ 对数恰为 $k$ 的不好算 那么可以先算 $a_i>b_i$ 对数至少 $k$ 的 这个排序后随便dp一下就好 那么再除了一下 用 $f_i$ 表示 $a_i>b_i$ 对数至少i的方案数 用 $g_i$ 表示 $a_i>b_i$ 对数恰为i的方案数 那么 $g_i=f_i(n-i)!-\sum_{j=i+1}^n g_jC(j,i)$ 其中,$(n-i)!$ 表示除了这 $i$ 个以外的所有元素的排列方式,$g_jC(j,i)$ 表示在 $j$ 个中任

bzoj 4767 两双手 - 动态规划 - 容斥原理

题目传送门 传送门I 传送门II 题目大意 一个无限大的棋盘上有一只马,设马在某个时刻的位置为$(x, y)$, 每次移动可以将马移动到$(x + A_x, y + A_y)$或者$(x + B_x, y + B_y)$.棋盘上有$n$个禁止位置不能经过,问马从$(0, 0)$走到$(E_x, E_y)$的方案数. 容斥是显然的. 每确定经过$k$个禁止位置的方案数的容斥系数是$(-1)^{k}$. 考虑带上容斥系数来动态规划, 注意到去掉重复的禁止位置后,$(0, 0), (E_x, E_y)