题目:
呵呵,这破题目搞了我两个小时,首先题意就有点怕怕的,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<m;i++) {
cin>>bug[i].nnum;
bug[i].id = i + 1;
maxn = max(maxn,bug[i].nnum);
}
for(int i=0;i<n;i++) {
cin>>stu[i].ablity;
stu[i].id = i + 1;
}
for(int i=0;i<n;i++)cin>>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<NODE> q;
for(int i=0,j=0;i<m;i+=t) {
for(;j<n;j++) {
if(stu[j].ablity >= 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<m;j++) {
tmp[bug[j].id] = qq.id;
mark++;
if(mark == t)break;
}
}
for(int i=1;i<=m;i++)ans[i] = tmp[i];
return true;
}
void cal() {
bool flag = false;
for(int i=0;i<n;i++) {
if(stu[i].ablity >= 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;
}
原文:http://blog.csdn.net/yitiaodacaidog/article/details/41522021