zoukankan      html  css  js  c++  java
  • [PA2014]Muzeum

    [PA2014]Muzeum

    题目大意:

    (n)件展品和(m)个警卫,每件展品有一个坐标((x_i,y_i))和价值(v_i),每个警卫的坐标为((x_i,y_i))。每个警卫面朝(y)轴负方向,左右视角都为( heta),警卫视线范围内的展品不能偷。你可以收买一些警卫,使其放弃安保工作,收买第(i)个警卫的价格为(v_i)。你需要收买一些警卫并偷走一些展品,求盗取的总价值(-)收买的支出的最大值。

    思路:

    ( an( heta)=frac wh),将所有点的(x_i)乘上(h)(y_i)乘上(w),再将所有点绕原点顺时针旋转(45^circ),则展品((u_i,v_i))((x_i,y_i))上的警卫监视,当且仅当(u_ile x_i)(v_ile y_i)

    将警卫当作“水源”,含(v_i)体积的水;展品当作“水桶”,容量为(v_i)。答案即为所有“水桶”容量之和(-)能被水桶吸收的水的体积。

    从左到右枚举每一个警卫,set中以纵坐标为序维护警卫左边的水桶的剩余容量。从高到低枚举不高于警卫所在位置的水桶,并尽可能将水装满即可。

    源代码:

    #include<set>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	register bool neg=false;
    	while(!isdigit(ch=getchar())) neg|=ch=='-';
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return neg?-x:x;
    }
    typedef long long int64;
    const int N=2e5+1;
    struct Point {
    	int64 x,y;
    	int v;
    	bool operator < (const Point &rhs) const {
    		return x==rhs.x?y<rhs.y:x<rhs.x;
    	}
    };
    Point a[N],b[N];
    std::set<std::pair<int64,int> > set;
    int main() {
    	const int n=getint(),m=getint();
    	const int w=getint(),h=getint();
    	int64 ans=0;
    	for(register int i=1;i<=n;i++) {
    		const int64 x=1ll*getint()*h,y=1ll*getint()*w;
    		a[i].x=x+y;
    		a[i].y=y-x;
    		a[i].v=getint();
    		ans+=a[i].v;
    	}
    	for(register int i=1;i<=m;i++) {
    		const int64 x=1ll*getint()*h,y=1ll*getint()*w;
    		b[i].x=x+y;
    		b[i].y=y-x;
    		b[i].v=getint();
    	}
    	std::sort(&a[1],&a[n]+1);
    	std::sort(&b[1],&b[m]+1);
    	for(register int i=1,j=1;i<=m;i++) {
    		for(;j<=n&&a[j].x<=b[i].x;j++) {
    			set.insert(std::make_pair(a[j].y,a[j].v));
    		}
    		while(b[i].v) {
    			std::set<std::pair<int64,int> >::iterator it=set.lower_bound(std::make_pair(b[i].y+1,0));
    			if(it==set.begin()) break;
    			std::pair<int64,int> p=*--it;
    			set.erase(it);
    			const int tmp=std::min(p.second,b[i].v);
    			b[i].v-=tmp;
    			p.second-=tmp;
    			ans-=tmp;
    			if(p.second) set.insert(p); 
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    有功功率和无功功率
    变压器的一些知识点
    服创大赛_思考
    AndroidsStudio_找Bug
    服创大赛第一次讨论_2019-1-14
    AndroidStudio_TextView
    JVM 专题十三:运行时数据区(八)直接内存
    JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位
    JVM 专题十一:运行时数据区(六)方法区
    JVM 专题十:运行时数据区(五)堆
  • 原文地址:https://www.cnblogs.com/skylee03/p/10165615.html
Copyright © 2011-2022 走看看