前言:

昨天深夜秒了不下6道题的其中一道.我以为我秒了,结果被卡bool了,不过也不错,可以复习一下bitset.

思路:


首先是一个简单的背包dp.


代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5,M=105;
bool f[M][N];
int main()
{
    int n,sum=0,l,r;scanf("%d",&n);f[0][0]=true;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&l,&r);
        for(int j=r;j>=l;j--)
        {
            for(int k=sum;k>=0;k--)
            {
                f[i][k+j*j]|=f[i-1][k];    
            }    
        }sum+=r*r;
    }int ans=0;
    for(int i=1;i<=sum;i++)    
        if(f[n][i])    ans++;
    printf("%d\n",ans);
    return 0;
}

然后就是用bitset优化这个空间.
还是一样的,假设我当前层数是f[i],那么我能转移的就是上层存在的+j*j的位子.用这两个运算就好了"<<","|"
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+2,M=101;
bitset<N>f[M];
int main()
{
    int n,sum=0,l,r;scanf("%d",&n);f[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&l,&r);
        for(int j=r;j>=l;j--)
        {
            f[i]|=(f[i-1]<<j*j);
        }
    }printf("%d\n",f[n].count());
    return 0;
}

emmm,复习了一下bitset,感觉很不错~