[CF521D]Shop

Posted skylee03

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;
}

以上是关于[CF521D]Shop的主要内容,如果未能解决你的问题,请参考以下文章

CF632E Thief in a Shop

CF632E: Thief in a Shop(快速幂+NTT)(存疑)

CF F. Shovels Shop(前缀和预处理+贪心+dp)

cf F. Shovels Shop

CF632E Thief in a Shop

如何从后台弹出片段