loj515 「LibreOJ β Round #2」贪心只能过样例[bitset+bool背包]

由于bitset极其不熟练且在实际题目中想不起来运用它来优化,于是练了几道题。

这题是一个分组的bool背包,每组必须选一个,暴力的话是$O(n^5)$。

如果dp数组不要一维滚动的话,有两种枚举方法,一种是枚举体积放外层然后同一组物品放内层,另一种是反过来。

for i 1...n
    for j 1...V
        for k 1...a[i]
            f[i][j]|=f[i-1][j-a[k]]
or
for i 1...n
    for k 1...a[i]
        for j 1...V
            f[i][j]|=f[i-1][j-a[k]]

然后注意第二种转移有一个可优化的地方。每次$f_{i-1,j}$都是固定向后移$a[k]$位的。这里可以把状态压成一个bitset,可以表出是1,那么整体右移$a[k]$位,取一下或,就是现在可以表出的。是不是很有道理。。于是这个$O(V)\to O(\frac{V}{64})$。

然后这题就可以了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<bitset>
 8 #define mst(x) memset(x,0,sizeof x)
 9 #define dbg(x) cerr << #x << " = " << x <<endl
10 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
11 using namespace std;
12 typedef long long ll;
13 typedef double db;
14 typedef pair<int,int> pii;
15 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
16 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
17 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
18 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
19 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
20 template<typename T>inline T read(T&x){
21     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
22     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
23 }
24 const int N=1e6+3;
25 bitset<N> f[2];
26 int n,l,r,now;
27 
28 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
29     f[0][0]=1;
30     read(n);while(n--){
31         read(l),read(r);f[now^=1].reset();
32         for(register int i=l;i<=r;++i)f[now]|=f[now^1]<<(i*i);
33     }
34     printf("%d\n",f[now].count());
35     return 0;
36 }
View Code

总结:bitset优化用途之一:判断每位是否可行,操作的时候可以直接整体修改。

posted @ 2019-10-22 16:42  Ametsuji_akiya  阅读(142)  评论(0编辑  收藏  举报