前言:
昨天深夜秒了不下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,感觉很不错~