zoukankan      html  css  js  c++  java
  • [CF521D]Shop

    [CF521D]Shop

    题目大意:

    你有一个长度为(k(kle10^5))的数列(A_{1sim k}),有(n(nle10^5))种操作,操作包含以下(3)种:

    1. (A_x)变成(y)
    2. (A_x)加上(y)
    3. (A_x)乘以(y)

    定义这个数列的收益为各项之积,你可以从中选(m)个操作(每个操作至多选(1)次),使得收益最大,求任一操作的方案。

    思路:

    贪心,对于只有操作(3)的情况,显然从大到小贪心更优。

    而操作(2)可以转化成操作(3),操作(1)又可以转化成操作(2),因此最后还是可以用同样的方式贪心。

    源代码:

    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<algorithm>
    #include<functional>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=1e5+1;
    int ans[N];
    std::pair<int,int> b[N];
    struct Modify {
    	int a,b,c;
    	bool operator > (const Modify &rhs) const {
    		return c>rhs.c;
    	}
    };
    Modify q[N];
    std::vector<std::pair<int,int> > v[N];
    struct Node {
    	int id;
    	double c;
    	bool operator < (const Node &rhs) const {
    		return c<rhs.c;
    	}
    };
    std::priority_queue<Node> h;
    inline bool cmp(const int &i,const int &j) {
    	return q[i].a<q[j].a;
    }
    int main() {
    	const int k=getint(),n=getint(),m=getint();
    	for(register int i=1;i<=k;i++) {
    		v[i].push_back(std::make_pair(getint(),0));
    	}
    	for(register int i=1;i<=n;i++) {
    		q[i].a=getint();
    		q[i].b=getint();
    		q[i].c=getint();
    		if(q[i].a==1) {
    			b[q[i].b]=std::max(b[q[i].b],std::make_pair(q[i].c-v[q[i].b][0].first,i));
    		}
    		if(q[i].a==3) {
    			h.push((Node){i,1.*q[i].c});
    		}
    	}
    	for(register int i=1;i<=k;i++) {
    		if(b[i].first>0) v[i].push_back(b[i]);
    	}
    	for(register int i=1;i<=n;i++) {
    		if(q[i].a==2) {
    			v[q[i].b].push_back(std::make_pair(q[i].c,i));
    		}
    	}
    	for(register int i=1;i<=k;i++) {
    		std::sort(v[i].begin()+1,v[i].end(),std::greater<std::pair<int,int> >());
    		int64 sum=v[i][0].first;
    		for(register unsigned j=1;j<v[i].size();j++) {
    			h.push((Node){v[i][j].second,1.*(sum+v[i][j].first)/sum});
    			sum+=v[i][j].first;
    		}
    	}
    	for(register int i=1;!h.empty()&&i<=m;i++) {
    		ans[++ans[0]]=h.top().id;
    		h.pop();
    	}
    	if(ans[0]==0) {
    		puts("0");
    		return 0;
    	}
    	std::sort(&ans[1],&ans[ans[0]]+1,cmp);
    	for(register int i=0;i<=ans[0];i++) {
    		printf("%d%c",ans[i]," 
    "[!(i%ans[0])]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    CEAA自动汇编脚本常用命令
    PIC之拉电流和灌电流
    CHARRANGE 结构
    汇编中的lodsb和stosb、lodsd和stosd指令
    汇编中的STOSB与STOSD指令
    汇编中的CLD指令
    SQL中distinct的用法
    SQL union介绍
    【项目排期】测试排期问题思考
    SQL join的介绍
  • 原文地址:https://www.cnblogs.com/skylee03/p/9715477.html
Copyright © 2011-2022 走看看