BZOJ 2024 SHOI2009 舞会 动态规划+容斥原理+高精度

题目大意:给定两个序列,求有多少个匹配满足a[i]<b[i]的对数不超过k对

见http://blog.csdn.net/popoqqq/article/details/44514113

高精度已废。。。

#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define M 202
using namespace std;
struct Big_Int{
	#define BASE 1000
	int num[125],cnt;
	Big_Int() {}
	Big_Int(int _)
	{
		memset(num,0,sizeof num);
		num[cnt=1]=_;
	}
	Big_Int& operator = (int x)
	{
		return *(new (this)Big_Int(x));
	}
	Big_Int& operator += (const Big_Int &x)
	{
		int i;
		cnt=max(cnt,x.cnt);
		for(i=1;i<=cnt;i++)
		{
			num[i]+=x.num[i];
			if(num[i]>=BASE)
				num[i+1]+=num[i]/BASE,num[i]%=BASE;
		}
		if(num[cnt+1]) ++cnt;
		return *this;
	}
	Big_Int operator + (const Big_Int &x) const
	{
		Big_Int re=*this;re+=x;return re;
	}
	Big_Int& operator -= (const Big_Int &x)
	{
		int i;
		for(i=1;i<=cnt;i++)
		{
			num[i]-=x.num[i];
			while(num[i]<0)
				num[i+1]--,num[i]+=BASE;
		}
		while( cnt>0 && !num[cnt] ) --cnt;
		return *this;
	}
	Big_Int operator - (const Big_Int &x) const
	{
		Big_Int re=*this;re+=x;return re;
	}
	friend Big_Int operator * (const Big_Int &x,const Big_Int &y)
	{
		int i,j;
		Big_Int re=0;
		for(i=1;i<=x.cnt;i++)
			for(j=1;j<=y.cnt;j++)
				re.num[i+j-1]+=x.num[i]*y.num[j];
		re.cnt=x.cnt+y.cnt;
		for(i=1;i<=re.cnt;i++)
			if(re.num[i]>=BASE)
				re.num[i+1]+=re.num[i]/BASE,re.num[i]%=BASE;
		if(!re.num[re.cnt]) re.cnt--;
		return re;
	}
	Big_Int& operator *= (const Big_Int &x)
	{
		return *this=*this*x;
	}
	friend ostream& operator << (ostream &_,Big_Int &x)
	{
		int i;
		printf("%d",x.num[x.cnt]);
		for(i=x.cnt-1;i>0;i--)
			printf("%03d",x.num[i]);
		return _;
	}
}f[M][M],g[M],C[M][M],fac[M],ans;
int n,k;
int a[M],b[M],next[M];
int main()
{
	int i,j;
	cin>>n>>k;
	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;
	}

	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];
	}
	for(fac[0]=1,i=1;i<=n;i++)
		fac[i]=fac[i-1]*i;

	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);
	}

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

	cout<<ans<<endl;
	return 0;
}
时间: 2024-11-16 16:45:24

BZOJ 2024 SHOI2009 舞会 动态规划+容斥原理+高精度的相关文章

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)

BZOJ 1064 假面舞会(图论-连通分量)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1064 题意:一年一度的假面舞会又开始了,栋栋也 兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理 1.首先我们去掉限制 假设 能够取 无数次 也就是说一开始把他当做完全背包来考虑 离线DP 预处理 复杂度 4*v 用f[ i ] 表示 空间 为 i 的方案数 答案ans 其实就是所有方案 - 所有超过限制的方案 限制指的就是题目中限制 某个硬币有几枚 然后所有超过限制的方案用容斥来做 所有超过限制的方案 要减 == -1 超过限制的方案 - 2 超过限制的方案 - 3 超过限制的方案 - 4 超过限制的方案 + 1和2 超

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>

图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]

BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1655  Solved: 798[Submit][Status][Discuss] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为

BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 110 using namespace std; struct abcd{ int to,next; bool ban; }table[M<<2]; int head[

BZOJ 3198 Sdoi2013 spring Hash+容斥原理

题目大意:给定n个元素,每个元素是一个六元组,求有多少对元素满足相同的位置恰好有k个 首先对于恰好有K个这种东西果断考虑容斥原理 我们2^6枚举相同的位置 恰好有k个元素相同的对数=至少有k个位置相同的对数-至少有k+1个位置相同的对数+至少有k+2个位置相同的对数-- 但是我们计数时会发现一些问题 比如下面这组样例显然是0: 2 3 1 2 3 4 5 5 1 2 3 4 6 6 但是这一对元素被加了C(4,3)次,只被减掉了C(4,4)次 因此我们将公式改成这样: 恰好有k个元素相同的对数=

BZOJ 1042 [HAOI2008]硬币购物 容斥原理

题意:链接 方法:容斥原理 解析:简单题,不掉坑都对不起我自己 这题很好想的一个容斥原理,因为一共只有四种硬币,我们不方便计算满足题中要求的方案数,但是从反向思考,我们需要做的就是减掉奇数个硬币用超额的情况,然后加上偶数个硬币用超额的情况就是最终的答案(当然状态是0000的时候看做是一个基准). 然后我没什么说的了,只是有一些细节需要注意下: 1.要用long long 2.完全背包千万不要傻到每次重新背,直接一次预处理就好,不过我为什么要重新背啊!(差了8s) 代码: #include <cs

BZOJ 2656 ZJOI 2012 数列(sequence) 高精度+记忆化搜索

题目大意:定义个一序列,f[i] = f[i / 2] (i % 2 == 0);f[i] = f[i / 2] + f[i / 2 + 1] (i % 2 == 1);求这个数列的第m项(m <= 10 ^ 100) 思路:数据范围高精度没跑了.记得之前做过这个题的弱化版,似乎是没有高精度的记忆化搜索,这个题就是加个高精度. CODE: #include <map> #include <cstdio> #include <cstring> #include &l