zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 4977 [Lydsy1708月赛]跳伞求生

    Description

    小Q最近沉迷于《跳伞求生》游戏。他组建了一支由n名玩家(包括他自己)组成的战队,编号依次为1到n。这个游

    戏中,每局游戏开始时,所有玩家都会从飞机上跳伞,选择一个目的地降落,跳伞和降落的时间有早有晚。在某局

    游戏降落前,他们在空中观察发现地面上一共有m间房子,编号依次为1到m。其中每间房子恰好有一名敌人早于他

    们到达。小Q战队的第i名玩家拥有a_i发子弹,地面上第i间房子里的敌人拥有b_i发子弹,消灭他可以获得c_i点积

    分。每名玩家必须且只能选择一间房子降落,然后去消灭里面的敌人。若第i名玩家选择了第j间房子,如果a_i>b_

    j,那么他就可以消灭该敌人,获得a_i-b_j+c_j的团队奖励积分,否则他会被敌人消灭。为了防止团灭,小Q不允

    许多名玩家选择同一间房子,因此如果某位玩家毫无利用价值,你可以选择让他退出游戏。因为房子之间的距离过

    长,你可以认为每名玩家在降落之后不能再去消灭其它房间里的敌人。作为小Q战队的指挥,请制定一套最优的降

    落方案,使得最后获得的团队奖励总积分最大

    Input

    第一行包含两个正整数n,m(1<=n,m<=100000),分别表示战队的玩家数和地面上的房间数。

    第二行包含n个正整数a_1,a_2,...,a_n(1<=a_i<=100000),分别表示每个玩家的子弹数。

    接下来m行,每行两个正整数b_i,c_i(1<=b_i,c_i<=100000),分别表示每个敌人的子弹数和奖励积分。

    Output

    输出一行一个整数,即最后获得的团队奖励总积分的最大值。

    Sample Input

    3 3  
    4 4 4  
    2 3  
    1 3  
    5 3
    

    Sample Output

    11
    

    Solution

    这题有很简单的做法,也有很复杂的做法

    这里写个简单的贪心

    首先把房子按照 (c_i-b_i) 排序,然后依次枚举,每次看第 (i) 个房子能不能被打掉,如果能就用大于 (b_i) 的最小 (a_j) 去打。但是这里并不代表钦定这个 (a_j) 去打 (b_i) ,因为不一定最优,这里只是把能打的房子先标记下来

    知道了哪些房子可以打掉,之后将 (a) 数组从大到小排序,用最大的 (a_j) 去打最大的 (c_i-b_i) ,使得获得收益最大。

    这里有两个细节

    • 会出现到一个 (c_i-b_i) ,它所对应的 (a_j) 其实打不了这个房子。但是这对答案是没有影响的,因为打掉这个房子的人在前面一定算过了。此时只需要把两者交换一下过程就可行了,但是不交换贡献是不会变的,所以直接算就好了
    • 题目要求的是最大权值,但不需要保证前提是打尽量多的房子,所以当我们枚举到某一次的贡献小于 (0) 的时候,就不需要再加了
    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=100000+10;
    int n,m,a[MAXN],in[MAXN],val[MAXN],cnt;
    ll ans;
    struct node{
    	int b,c;
    	inline bool operator < (const node &A) const {
    		return c-b>A.c-A.b;
    	};
    };
    node room[MAXN];
    std::multiset<int> S;
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    int main()
    {
    	read(n);read(m);
    	for(register int i=1;i<=n;++i)read(a[i]),S.insert(a[i]);
    	for(register int i=1;i<=m;++i)read(room[i].b),read(room[i].c);
    	std::sort(room+1,room+m+1);
    	for(register int i=1;i<=m;++i)
    	{
    		std::set<int>::iterator it=S.upper_bound(room[i].b);
    		if(it!=S.end())val[++cnt]=room[i].c-room[i].b,S.erase(it);
    	}
    	std::sort(a+1,a+n+1,std::greater<int>());
    	for(register int i=1;i<=cnt;++i)
    		if((ll)a[i]+val[i]>0)ans+=(ll)a[i]+val[i];
    	write(ans,'
    ');
    	return 0;
    }
    
  • 相关阅读:
    Git简介
    git 目录
    版本控制系统介绍
    python 爬虫 基于requests模块发起ajax的post请求
    python 爬虫 基于requests模块发起ajax的get请求
    POJ 2575
    POJ 2578
    POJ 2562
    POJ 2572
    POJ 2560
  • 原文地址:https://www.cnblogs.com/hongyj/p/9518125.html
Copyright © 2011-2022 走看看