【每日一题】5月20日 背包 bitset
简单瞎搞题
https://ac.nowcoder.com/acm/contest/5556/E
题意
共有 n个数,第 i 个数是 xixi 可以取 [li , ri] 中任意的一个值。
设 ,求 S 种类数。
输入描述
第一行一个数 n。
然后 n 行,每行两个数表示 li,ri。
输出描述
输出一行一个数表示答案。
解析
这个题目就一看就是dp呀,怎么看出来时dp的我就不多少了,就是每一个数都要从那个范围了取然后推过去,我这里讲一下用bitset实现的思路,感谢jxy大佬的认真讲解,首先我们看下bitset是啥,这个可以理解成bool数组和字符串的结合体,bitset<4> bitset1;
这样就定义了一个长为4的bitset,名字为bitset1,默认每一位都为0,bitset每一位只有1和0两种情况,然后我们来看怎么用bitset来解决这个问题,首先我们一定是直接来看我怎么实现
先看代码,今天打破我固定的格式
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=1e6+5; int main(void){ bitset<MAXN>ans; ans[0]=1; int l,r,n; cin>>n; while(n--){ cin>>l>>r; bitset<MAXN>temp; for(int i=l;i<=r;++i)temp|=ans<<i*i; ans=temp; } cout<<ans.count()<<endl; //输出ans中1的个数 return 0; }
我们一点一点来推,就能看明白是怎么dp的,首先我们定义一个长达MAXN的数组,从0开始,当只有0个数字时,只有一种情况,所以ans[0]=1;然后我们推第一个数,第一个数的范围为[1,2],首先ans左移11个字符,也就是从ans=0001,移到了ans=0010,temp就等于0010,然后时2,ans向左移22,ans=1000,这时temp就等于1010,也就是成功记录了加入一个数之后两次的结果,同理后面的都是这么推,然后我们就可以成功的记录最后一共有多少种情况,最后只要计算ans中一共有多少个1就好了。
每日一题 文章被收录于专栏
写每日一题呀