ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF521D Shop

2019-10-28 14:56:07  阅读:240  来源: 互联网

标签:Shop 乘法 int cnt1 加法 CF521D id 赋值


题意

\(n\)个数,有\(m\)个操作,形如:

  1. 将\(x_i\)改成\(val_i\)
  2. 将\(x_i\)加上\(val_i\)
  3. 将\(x_i\)乘上\(val_i\)

现在你可以从中选择最多\(k\)个操作(不能重复选),并按一定顺序执行,使得\(\prod_{i=1}^{n}x_i\)
第一行输出选择的操作个数,第二行按执行顺序输出方案。

思路

先考虑,一定先进行赋值,再加,再乘。

如果只有乘法,对答案的贡献都只与乘的数相关。所以我们可以直接按操作的值排序,贪心即可。

接着对于赋值,显然对于一个数只会进行一次,一定赋值为最大的(如果小于原数,不如不做)。那么其实就可以看成是加法了(但一定要在第一个加)

现在的问题是加法如何转化为乘法。对于同一个数,加法肯定是从大到小按先后执行的,按加数大小排序,也就是说,如果进行了操作\(i\),那么\(1,2,...n-1\)都一定进行了。因此就可以将加法转化为乘法,设\(S_i=a_1+...a_i\),考虑第\(i+1\)个操作,即把\(S_i\)变成了\(S_{i+1}\),也就是乘上了\(\frac{S_{i+1}}{S_i}\),这样子就可以都变成乘法贪心了。

但是我突然产生了一个疑问,赋值变为加(简称赋值加)后能跟所有加法一起处理吗?分类思考:

  • 若赋值加没有被加入,答案显然是不受影响的;
  • 若赋值加被加入,把所有乘法乘起来后,可以约分,发现答案就是\(S_x\),不受顺序影响,所以贪心是正确的

在输出时只要注意按赋值、加、乘、输出即可。

#include <bits/stdc++.h>
const int N=100005;
int n,m,k,a[N],op,p,x,cnt1,cnt2,t[N];
struct note{
    int p,x,id;
}b[N],c[N];
struct node{
    int p,id;
    double x;
}d[N];
bool cmp(note x,note y){
    return x.p==y.p?x.x>y.x:x.p<y.p;
}
bool cmp2(node x,node y){
    return x.x>y.x;
}
bool cmp3(node x,node y){
    return t[x.id]<t[y.id];
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=m;i++){
        scanf("%d%d%d",&op,&p,&x);
        if (op==1 && x>b[p].x && x>a[p]) b[p]={p,x,i},t[i]=1;
        else if (op==2) c[++cnt1]={p,x,i},t[i]=2;
        else if (op==3 && x>1) d[++cnt2]={p,i,x},t[i]=3;
    } 
    for (int i=1;i<=n;i++) if (b[i].x>0) c[++cnt1]={i,b[i].x-a[i],b[i].id};
    std::sort(c+1,c+cnt1+1,cmp);
    long long sum=0;
    for (int i=1;i<=cnt1;i++){
        int p=c[i].p,x=c[i].x;
        if (p!=c[i-1].p)
            sum=a[p];
        d[++cnt2]={p,c[i].id,(sum+x)*1.0/sum};
        sum+=x;
    }
    std::sort(d+1,d+cnt2+1,cmp2);
    k=std::min(k,cnt2);
    printf("%d\n",k);
    std::sort(d+1,d+k+1,cmp3);
    for(int i=1;i<=k;i++) printf("%d ",d[i].id);
}

标签:Shop,乘法,int,cnt1,加法,CF521D,id,赋值
来源: https://www.cnblogs.com/flyfeather6/p/11752200.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有