比赛链接
@[toc]

题目描述

在这里插入图片描述
输入描述:

第一行一个数 n。 然后 n 行,每行两个数表示 li,ri。

输出描述:

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

示例1
输入

5
1 2
2 3
3 4
4 5
5 6

输出

26

备注:
1 ≤ n , li , ri ≤ 100

题解:

xi的是在 [li , ri]中任选一个,然后构成值,所以可以用分组背包来做
dp[i][j]前i个数字能否构成j
那么dp [ i -1 ] [ j - x[ i ]* x [ i ] ] = = 1则说明加上第i个数则可以构成,x [ i ] 的取值范围 是题目所给 l[i]和r[i]
这样做肯定不行,哪那么简单
复杂度过高,我们需要压缩下
先注意dp的值无疑是0或1,所以可以用bitset.
bitset 在 bitset 头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。
这样,我们用dp [ i ]表示第i行的01串
dp [ i ]= dp [ i ] | ( d p [ i - 1 ] < < ( x [ j ] ^2^ ) )
bitset还有自带的求1的个数的count,这样就更方便了

代码:

#include<bits/stdc++.h>
#include<bitset>
using namespace std;
typedef long long ll; 
int num1,num2; 
const int maxn=130;
int a[maxn]; 
bitset<1000009>dp[130];
int n;
int main(){ 
      cin>>n;
      dp[0][0]=1;
      for(int i=1;i<=n;i++)
      {
          int l,r;
          cin>>l>>r;
          for(int j=l;j<=r;j++)
          dp[i]|=(dp[i-1]<<(j*j));
    }
    cout<<dp[n].count();
    return 0;
}