HDU4864 贪心+STL

原题HDU4864
Sample Input
1 2
100 3
100 2
100 1
Sample Output
1 50004

题目大意

条件:
Task xi,yi
Machine xj,yj
只有xj>xi&&yj>yi task才可以被执行
收益:500*xi+2*yi
求解:
输出多可以被解决的task和最多的收益

解题-贪心

收益最大
主要考虑x(对收益影响大)
收益由被解决的task决定
task按照x从大到小排序(相同按照y),越前task收益越大,从前往后解决的task越多,收益越大。
? 收益最大状态<=>task解决最多状态?

为什么这么贪心,因为若还存在任务(xk,yk)使得这个机器能被使用,但xj>=xk,所以获得金钱更多,优先选择j;若k不能使用这个机器,那么必定也就不存在其他机器能被使用,除非是新加入的机器,但新加入的必定不能完成任务j,所以完成任务保证了最多。
https://blog.csdn.net/a601025382s/article/details/38046927

解决最多
主要考虑y(对收益影响没有x大,但是限制解决个数,x优先排序已经解决)
寻找可以解决当前task的machine(此时收益已定)
选择y最小的machine(留大的解决更多问题)
tips
因为是按照x优先排序的,所以可以解决之前task的machine,x一定满足解决之后task。
与HDU4268类似

变量-伪代码

#define N 100005
struct node{
intx,y;
}task[N],machine[N];
#include< set >
multiset< int > myset;
multiset< int > :: iterator it;
int n,m;
int cnt;
long long sum; printf(“%I64d”,sum);

输入 n,m,task[],machine[]
sort()task[],machine[]从大到小
遍历task[i]
    当(找到了x满足的machine)
        存放y在myset
        继续找j++;
    如果有x满足的话
        找第一个>=task[i].y的machine.y//lower_bound()
    找到了的话//没找到!it=myset.end()越界
        cnt++;算sum;
        删除这个machine.y(保留其他machine.y)
输出cnt sum

AC代码

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<set>
#define N 100005 
#define LL long long
using namespace std;
struct node{
    int x,y;
}task[N],machine[N];
multiset<int> myset;
multiset<int>::iterator it;
bool cmp(node n1,node n2){
    if(n1.x==n2.x)
        return n1.y>n2.y;
    return n1.x>n2.x;
}
int main(){
    ios::sync_with_stdio(false);
    int i,j;
    int n,m;
    int cnt;
    LL sum;
    while(cin>>n>>m){
        cnt=sum=0;myset.clear();
        for(i=0;i<n;i++)
            cin>>machine[i].x>>machine[i].y;
        for(i=0;i<m;i++)
            cin>>task[i].x>>task[i].y;
        sort(machine,machine+n,cmp);
        sort(task,task+m,cmp);
        j=0;
        for(i=0;i<m;i++){
            while(j<n&&machine[j].x>=task[i].x){
                myset.insert(machine[j].y);
                j++;
            }
            if(myset.size()){
                it=myset.lower_bound(task[i].y);
                if(it!=myset.end()){
                    cnt++;sum+=500*task[i].x+2*task[i].y;
                    myset.erase(it);
                }
            }
        }
        printf("%d %I64d\n",cnt,sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42946476/article/details/81607061