Educational Codeforces Round 160 (Rated for Div. 2)
C. Game with Multiset
题目链接
题意:
一开始有个空的多重集(元素之间可以重复),有两个操作。
- 给定x,向多重集加入一个元素 2 x 2^x 2x
- 给定w,询问多重集选择若干个元素(不能重复选取一个元素)是否可以凑出w
思路:
这能1300分?有点氵。思路就是贪心,从大到小拿元素去减,能减掉就把这个元素选上,否则就跳过。能这样做的根本原因就是二进制低位同一位有两个1就可以向高位进位,换句话说就是两个小数能干的事,大数一定能干,不存在多个小数无法被大数替代的情况,所以先选取大数,后面小数肯定选的就少了,多的能拿,少了更能拿出来了,不会影响后面选取。所以不如我们一开始就把不灵活的大数算进去。
code:
#include <iostream>
#include <cstdio>
using namespace std;
int T,op,x;
int cnt[35];
int main(){
cin>>T;
while(T--){
cin>>op>>x;
if(op==1)cnt[x]++;
else {
for(int i=29,t;i>=0;i--){
t=min(cnt[i],(x/(1<<i)));
x-=t*(1<<i);
}
if(x)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
return 0;
}