#515. 「LibreOJ β Round #2」贪心只能过样例 背包+bitset优化

来源:互联网 发布:黑客帝国4矩阵复活剧照 编辑:程序博客网 时间:2024/06/01 11:26

pdf



题意:

一共有 nnn个数,第 iii 个数 xix_ixi 可以取 [ai,bi][a_i , b_i][ai,bi] 中任意值。
设 S=∑xi2S = \sum{{x_i}^2}S=xi2,求 SSS 种类数。

输入格式

第一行一个数 nnn
然后 nnn 行,每行两个数表示 ai,bia_i,b_iai,bi

输出格式

输出一行一个数表示答案。

样例

样例输入

51 22 33 44 55 6

样例输出

26

数据范围与提示

1≤n,ai,bi≤1001 \le n , a_i , b_i \le 1001n,ai,bi100


思路:

正常情况下我们会想用背包来求解这个问题, f[ i ][j]=f[i-1][j-k*k] 但是要枚举没个j,

这里j的话最大到 100*100*i,又要枚举(a,b) 所以这样肯定会超时了.

有一个比较神奇的做法就是利用bitset来优化这个问题,bitset<1e6+10>b[101]  

我们假设b 中的每一位从最低位0开始, 如果第i位为1 就意味着可以加出和为i的s.为0就

表示不可以... 那么当我们要要加上一个x的时候怎么办呢,只需要将b【k-1】中对应的为1的位置左移x*x位给b[k],表示

加完第k个数后可以合出这样的s.

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=1e6+10;int n;int l,r;bitset<maxn>b[111];int main(){scanf("%d",&n);b[0].set(0);for(int i=1;i<=n;i++){b[i].reset();scanf("%d %d",&l,&r);for(int j=l;j<=r;j++){b[i]|=(b[i-1]<<(j*j));}}printf("%d\n",b[n].count());return 0;}

阅读全文
0 0
原创粉丝点击