zoukankan      html  css  js  c++  java
  • 【题解】NOI2017 蔬菜(贪心)

    【题解】NOI2017 蔬菜(贪心)

    考虑这样一个事实:

    假如你在很长的一段时间内卖了很多蔬菜,但其中只有(p)天你卖了菜。那么其实你在(p)天内也可以完成同样的操作。

    这是因为

    1. 菜的收益不随时间而改变
    2. 菜不存在体积的区别

    题目每天消失固定(x_i)蔬菜的限制可以看做每个蔬菜有一个消失时间,每天只能消失(m)个蔬菜,那么我们就先卖消失时间靠后的蔬菜。那么问题就变得简单了。现在就是给定一个(p),求最大的(jle p)使得(j)还有容量,是并查集。

    分析一下这里并查集(路径压缩)的复杂度,设查询次数为(q),复杂度为(O(q+1e5*m))。(因为一个点只会被访问m次)

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    using namespace std;  typedef long long ll;
    inline int qr(){
    	int ret=0,f=0,c=getchar();
    	while(!isdigit(c)) f|=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    
    const int maxn=1e6+5;
    int n,m,k;
    int a[maxn],s[maxn],c[maxn],x[maxn],r[maxn],sav[maxn],cnt;
    ll ans[maxn];
    int Find(int x){return x==r[x]?x:r[x]=Find(r[x]);}
    priority_queue< pair<int,int> > q;
    
    int main(){
    	n=qr(),m=qr(),k=qr();
    	for(int t=1;t<=n;++t)
    		a[t]=qr(),s[t]=qr(),c[t]=qr(),x[t]=qr(),q.push((pair<int,int>){a[t]+s[t],t});	
    	for(int t=1;t<=1e5;++t) r[t]=t,sav[t]=m;
    	while(q.size()){
    		pair<int,int> now=q.top(); q.pop();
    		int tar=0;
    		if(x[now.second]) tar=Find(min(100000,(c[now.second]-1)/x[now.second]+1));
    		else tar=Find(100000);
    		if(!tar) continue;
    		--c[now.second]; ans[cnt+1]=ans[cnt]+now.first; ++cnt; --sav[tar];
    		if(!sav[tar]) r[Find(tar)]=Find(tar-1);
    		if(c[now.second]) q.push((pair<int,int>){a[now.second],now.second});
    	}
    	while(k--) cout<<ans[min(cnt,m*qr())]<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    搭建博客
    开发常用的工具函数
    堆内存和栈内存及C++内存分配
    nuxt本机运行,如何用ip访问,localhost也可以访问?
    vue封装一个左滑删除的组件
    vue封装一个swiper组件
    YAPI安装google的cross-request插件
    vue项目中如何封装api,使请求方法清晰,适合协作开发
    axios封装一个请求本地数据的方法
    nuxt中vuex如何模块化分
  • 原文地址:https://www.cnblogs.com/winlere/p/12320674.html
Copyright © 2011-2022 走看看