[bzoj3371][poj2009][Usaco2004 Mar]Moo University - Emergency Pizza Order 定制比萨饼
标题这么长的。。真是让感觉人头大脚轻。
贴题面先。
Description
Input
Output
Sample Input
2 2 1
1 1
1 2
Sample Output
样例说明
只能生产两种饼:一个有1号馅的比萨饼和一个有2号馅的比萨饼。第一个饼给第1号牛,第二块饼给3号牛,这样两头牛被喂饱了.同时将三头都喂饱的办法不存在。
题面并不是很容易看懂,理解应该是没问题的。重要的几句话是:
1:不能有两头牛的pizza组成完全相同。
2:一个pizza上必须有且仅有k种馅料。
3:pizza上的馅料不能重复。
以上就是说每头牛的喜好与pizza的构成可以用一个01串或者bitset来表示,且是1的位有且只有k个,pizza之间互不相同。
4;一头牛能与一个pizza匹配当且仅当牛的01串中为0的位,pizza的01串也是0。
Claris说是暴搜啊?!仔细看看确实是。但大概还是基于二分图匹配的暴搜。
目前正在研究,如果想不想看我口胡的非正解非满分做法,请右上角关闭页面然后等我完善再来看。
口胡部分:
这道题我并没有A,拿到了80pts。做法基于二分图匹配但还包含贪心。很玄乎,给大家提供思路而已。
看起来就是个二分图匹配,但是数据范围?有30种馅料,最多可以存在$\binom{15}{30}$大约$1e12$种pizza。但最终能匹配的能有几个?显然不会超过n。如果枚举所有的点,连上所有的边,额,呵呵。
所以显然不能按上面说的那样来做。需要在寻找增广路的时候,动态寻找。
具体实现:
首先能跟给定奶牛匹配的pizza,我们说过,必须在奶牛为0的位上也是0。但我们要凑够k种馅料,所以还需要在保证上述要求的情况下,填上k个1。我们假设当前奶牛喜欢t种馅,即不喜欢m-t种馅,即有m-t位为0。显然t<k的牛什么也给不了,挑食太多就没法满足。其他的牛呢?我们这k位怎么填?我的做法是按照枚举的顺序填就行,先向靠前的位填1,直到填完。然后我们得到一个01串,可以将其转成int之后用map来存储这个pizza是否被其他牛占领过了。
下面是出现问题的地方。
如果已经被占领过,比较当前牛和之前占领的牛哪一个喜欢的馅料多。由喜欢馅料多的牛做出让步,把这个pizza让给少的,因为它更矫情,更难满足。而且如果两头牛能一起抢一个pizza,pizza一定是两头牛的喜好的交集。这个贪心我并不会证明是正确的,而且最尴尬的在于两头牛喜欢的馅料数相等,还不完全相同,比如(1,3,4)和(3,4,5)抢(3,4),并不好说给谁。我的做法里默认先来后到,所以会有错误。
略过这里不提,按如上方法增广,如果不能增广就表示这个牛匹配不到pizza。每头牛匹配完,即可得出答案。
Tips:其实还有很难解决的一个地方,就是如何按顺序枚举在(m-t)个空位上填入k个1。我发现了一位博主的做法用了上去。很强。
因为还没有做出正解,所以希望有dalao可以切掉这道题并告诉本蒟蒻怎么解决错误的贪心或者正解也好!
附80pts
#include<iostream>
#include<cstdio>
#include<bitset>
#include<map>
using namespace std;
map<int,int>g;
int n,m,k,cnt=;
int nxtC(int k,int lim){
int ret,b=k&-k,t=(k+b);
ret=(((t^k)>>)/b)|t;
if(ret>=<<lim)
return ;
return ret;
}
void find(int x){
bitset<>b(x);
int f[],top=,c=m-b.count();
for(int i=;i<m;i++)
if(b[i])f[top++]=i;
int ik=(<<k)-;
do{
bitset<>t;
for(int i=;i<top;i++)
if(ik&(<<i))
t[f[i]]=;
int y=t.to_ulong();
if(!g[y]){
g[y]=x;cnt++;return;
}
else{
int r=g[y];
bitset<>tmp(r);
if(tmp.count()<=m-c)
continue;
g[y]=x;
find(r);
return;
}
}while(ik=nxtC(ik,top));
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++){
int t;scanf("%d",&t);
bitset<>p;
for(int i=;i<=t;i++){
int x;scanf("%d",&x);
p[x-]=;
}
if(t<k)continue;
find(p.to_ulong());
}
cout<<cnt;
}
注:nxtC(int k,int lim)即求出当前为k(int表示的01串)的下一个$\binom{K}{lim}$组合。
如:nxC(11(10102),5)返回的应该是12(11002),即四选二的1010的下一个组合。枚举顺序从小到大。
注意函数带的参数k并不是组合数里的K。我的变量有的定义在函数里有的是全局,组合数的K是全局的那个,但在nxC函数里是失效的,也就是说nxC函数并不需要知道要填几个1,因为根据上一个状态就能知道有几个1了。
9.6更
昨天向Claris要到了代码!!鸡冻!!
我的做法貌似思想是没有错的,出现问题的部分其实是完全可删的。并不需要那个不正确的贪心来稳定复杂度,因为数据其实很小。而枚举下一状态的时候其实放在匈牙利的dfs函数里就行,Claris代码的框架就是:匈牙利的dfs,在判断dfs(match[已经占过这个状态的牛])的时候重新从初状态开始枚举,也就是把深搜枚举下一状态的dfs嵌套在匈牙利的dfs中。实在是喵啊!额复杂度我并不会分析。。
[bzoj3371][poj2009][Usaco2004 Mar]Moo University - Emergency Pizza Order 定制比萨饼的更多相关文章
- Divide and conquer:Moo University - Financial Aid(POJ 2010)
Moo University - Financial Aid 其实是老题了http://www.cnblogs.com/Philip-Tell-Truth/p/4926008.html 这一次我们换二 ...
- Moo University - Financial Aid
Moo University - Financial Aid Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6020 Accep ...
- poj 2010 Moo University - Financial Aid
Moo Univ ...
- POJ 2010 Moo University - Financial Aid( 优先队列+二分查找)
POJ 2010 Moo University - Financial Aid 题目大意,从C头申请读书的牛中选出N头,这N头牛的需要的额外学费之和不能超过F,并且要使得这N头牛的中位数最大.若不存在 ...
- BZOJ 3375: [Usaco2004 Mar]Paranoid Cows 发疯的奶牛( set )
果然写得短就跑得慢... 直接用set就行了(你要写棵平衡树也可以).没有包含的话, 假如L(i) <= L(j), 那么R[i] <= R[j]. 所以从小到大扫, 每次查找左端点小于当 ...
- BZOJ 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜( 差分约束 )
枚举每头牛, 假设它在说谎, 建图判圈就行了...为啥水题都没人来写.. --------------------------------------------------------------- ...
- bzoj 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜
3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜 Description 兽群中总是有一些麻烦制造者.约翰知道他的N(1≤N≤100)头奶牛中有一头总是说谎,其他的 ...
- 【POJ - 2010】Moo University - Financial Aid(优先队列)
Moo University - Financial Aid Descriptions 奶牛大学:奶大招生,从C头奶牛中招收N(N为奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新 ...
- poj 2010 Moo University - Financial Aid 最大化中位数 二分搜索 以后需要慢慢体会
Moo University - Financial Aid Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6599 A ...
随机推荐
- 升级jdk注意事项
最好使用和编译的jdk相同版本的jre去执行.class程序. 今天在本地模拟部署项目到tomcat6就遇到了个坑. 我们项目使用的jdk1.7开发的,编译打war包放到webapps后,启动报错Ex ...
- 支付宝快速集成ios
看一下这篇文章,非常不错,并在此感谢这篇文章的作者. 惯例,先写出嵌入支付宝的核心代码 - (IBAction)payWithAli:(UIButton *)sender { //生成订单信息NSSt ...
- python 爬图片
学了两天python,语法慢慢熟悉吧,数据结构都没写过. 写了一个爬图片的小东西.挺有意思的.都是女神照 (✿◡‿◡) 用的是正则表达式, ''' 符号: . 匹配任意字符,\n除外 * 匹配前一个字 ...
- 【转】Android tools:context
tools:context="com.example.guolin.scrollertest.MainActivity" 有时候可以看到有这个东西,但是从来没有用过,不知道有什么作 ...
- Family Gathering at Christmas(思维题)
Family Gathering at Christmas 时间限制: 1 Sec 内存限制: 128 MB提交: 13 解决: 4[提交] [状态] [讨论版] [命题人:admin] 题目描述 ...
- 20145238-荆玉茗 《Java程序设计》第8周学习总结
20145238 <Java程序设计>第8周学习总结 教材学习内容总结 第15章 通用API 15.1.1 ·java.util.logging包提供了日志功能相关类与接口,使用日志的起点 ...
- Laplace算子和Laplacian矩阵
1 Laplace算子的物理意义 Laplace算子的定义为梯度的散度. 在Cartesian坐标系下也可表示为: 或者,它是Hessian矩阵的迹: 以热传导方程为例,因为热流与温度的梯度成正比,那 ...
- Shell编程学习之Shell编程基础(一)
这篇随笔将要介绍关于Shell编程的基本知识,这些将会在假设你已经熟悉了Linux系统和命令行的基本知识. 构建基本脚本 你应该了解或熟悉使用Shell命令行了,但是只是使用Shell命令行的命令,有 ...
- 【Java-POJO-设计模式】JavaEE中的POJO与设计模式中多态继承的冲突
最近看<重构>谈到利用OO的多态来优化 if else 和 switch 分支语句,但是我发现OO语法中的多态在使用框架的JavaEE中是无法实践的.对此,我感到十分的疑惑,加之之前项目中 ...
- Java中的逻辑运算符短路效应
在Java中逻辑运算符&& 和 ||,它们都存在短路效应. 对于a && b,只有当a和b同时为true时,整个表达式才为true(在java中,首先运算表达式a,如果 ...