codeforces每日两道思维题(第 五 天)

C. Game with Multiset

rating :未知

原题链接:Problem - C - Codeforces

题意描述:

在这个问题中,最初会给你一个空的多集。您必须处理两种类型的查询:

在这个问题中,最初会给你一个空的多集。您必须处理两种类型的查询:

  1. ADD x - 在多集合中添加一个等于 2^x 的元素;
  2. GET w - 询问是否可以取当前多集的某个子集之和,并得到等于 w 的值。

解题思路:贪心策略,每次从最后往前开始找,只要能减就减掉,总共29个数字

完整代码:

#include<iostream>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
int main(){
    int n;
    cin>>n;
    vector<int>cnt(30,0);
    while(n--){
        int t,v;
        cin>>t>>v;
        if(t==1){
            cnt[v]++;
        }
        else{
            // 贪心策略 从大到小,将尽可能大的都删掉,剩下的小的开始穿插补齐
            for(int i=29;i>=0;i--){
                //这里的cnt[i]代表当前i有几个
                //如果cnt太多,那么我们肯定不会删掉cnt,我们只需要删掉对应数量的i就行
                //就用当前的v>>i
                //只有当cnt[i] 大于 v>>i 才会用v 
                v-=min(v>>i,cnt[i])<<i;
           
               // if((v>>i)>=cnt[i])v-=(cnt[i]<<i);
            }
            if(v<=0){
                cout<<"YES"<<endl;
            }
            else{
                cout<<"NO"<<endl;
            }
            
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海风许愿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值