好博客: https://www.cnblogs.com/cjjsb/p/9751384.html
例题1:
题目链接:https://www.nowcoder.com/acm/contest/132/C
题意:
分析:核心就在于看作01背包的形式,枚举种类n,每个范围(L-R+1),以及所有的可能值 1~1e6,
然后直接做的话又会超时,所以要用到 bitset 的位运算,将b[0][0]设置为1,每次向左移动 j*j 位,最后就可以得到经过所有组合后的可能取值。
#include <cstdio> #include <bitset> using namespace std; bitset<1000005>b[105]; int n,l[105],r[105]; int main() { scanf("%d",&n); int Min=0; for(int i=1;i<=n;i++) {scanf("%d%d",&l[i],&r[i]); Min+=l[i]*l[i];} b[0].set(0); //上面那句就等同于 -> b[0][0]=1; for(int i=1;i<=n;i++) for(int j=l[i];j<=r[i];j++) b[i]|=(b[i-1]<<(j*j)); // int ans=0; // for(int i=Min; i<=1000005; i++){ // if(b[n][i]) ans++; // } // printf("%d\n", ans); printf("%d\n",b[n].count()); return 0; }