CodeForces 377B 优先队列 + 二分

2015-01-27 06:07:29 · 作者: · 浏览: 6

题目:

呵呵,这破题目搞了我两个小时,首先题意就有点怕怕的,n个人,具有解决bug的能力,一天只能解决一个,m个bug,bug具有一个难度,只有某个人能力大于等于这个难度才可以解决,请n个人解决一个问题,每个人都要拿钞票的,问不超过s元 的情况下 最快的解决办法

输出每个bug由哪个人解决的方案

先考虑了DP,发现不行,后来就觉得是贪心了,那么就跟优先队列联系上了,把bug的难度 跟人的 解决办法能力都从大到小排,然后开始二分枚举解决天数,假设解决天数为t,那么最厉害的那个人且花费比较合适的那个人最多使用t次,都从大到小排,然后再优先队列一下能解决问题的花费最少的人,每一次更新,若他能解决第一个问题,那么接下里的 t-1个问题他都可以解决,更新是从前往后更新的,所以肯定是最优的,中间花费超过s的方案可以舍去,没办法解决当前未解决的最大难度的bug也要舍去,二分枚举的 最后一个能成功的肯定就是最优的了,

一开始 看看是否最难的bug有人能够解决,否则 输出No

还要看看m天是否有解决方案,因为最多是使用m天,若无法解决那么输出no

接下来才枚举天数

一开始没相当去枚举解决时间,结果弄得很麻烦,后来想到了,敲了,结果中途优先队列有个地方手贱敲错了,一直在调试解决函数,真是醉了。。


int n,m,s;

typedef struct Node {
	int id;
	int nnum;
	bool operator<(const Node &aa)const {
		return nnum > aa.nnum;
	}
};

Node bug[100000 + 55];

typedef struct NODE {
	int id;
	int ablity;
	int cost;
	bool operator<(const NODE & aa)const {
		return cost > aa.cost;
	}
};

NODE stu[100000 + 55];

int maxn;

int ans[100000 + 55],tmp[100000 + 55];

void init() {
	memset(bug,0,sizeof(bug));
	memset(stu,0,sizeof(stu));
}

bool input() {
	while(cin>>n>>m>>s) {
		maxn = -1;
		for(int i=0;i
  
   >bug[i].nnum;
			bug[i].id = i + 1;
			maxn = max(maxn,bug[i].nnum);
		}
		for(int i=0;i
   
    >stu[i].ablity; stu[i].id = i + 1; } for(int i=0;i
    
     >stu[i].cost; return false; } return true; } bool cmp(NODE x,NODE y) { return x.ablity > y.ablity; } bool isok(int t) { int ret = 0; priority_queue
     
       q; for(int i=0,j=0;i
      
       = bug[i].nnum)q.push(stu[j]); else break; } if(q.size() == 0)return false; NODE qq = q.top(); q.pop(); ret += qq.cost; if(ret > s)return false; int mark = 0; for(int j=i;j
       
        = maxn && stu[i].cost <= s)flag = true; } if(!flag) {puts("NO");return;} sort(bug,bug + m); sort(stu,stu + n,cmp); int cc = 0; if(!isok(m)){puts("NO");return ;} int l = 1,r = m; while(l <= r) { int mid = (l + r)>>1; if(isok(mid))r = mid - 1; else l = mid + 1; } puts("YES"); for(int i=1;i<=m;i++) printf("%d%c",ans[i],i == m?'\n':' '); } void output() { } int main() { while(true) { init(); if(input())return 0; cal(); output(); } return 0; }