[NC17193]简单瞎搞题(bitset)
题目
思路
先思考暴力做法,每组依次判断能否和桶里的数组成一个新的数,能则为1;
最后遍历一边桶数组,计算ans
T:1e6 * 100 * 100
K:1e6, 100, 100;
dp做法:
dp[100][1e6]
1.dp[i][j]表示从前i层里选到j的情况是否存在
2.if dp[i - 1][sum] == 1 dp[i][j * j + sum] == 1;
3.初始化为0,dp[0][0] = 1
优化:
因为dp数组的大小为1e8超了内存,不能直接用bool数组存,所以需要用bitset优化
bitset<1e6 + 10> dp[100]
就有dp公式:dp[i] = dp[i] | dp[i - 1] << j * j
就相当于dp数组每位存的是十进制下这个数是否存在,通过或运算来转移前一个的状态
最后统计dp[n]里1的个数即可求出答案
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
bitset<N> dp[110];
int main(){
int n;
cin >> n;
int l, r;
int sum = 0;
for(int i = 1; i <= n; i ++){
cin >> l >> r;
dp[0] = 1;
for(int j = l; j <= r; j ++){
dp[i] = dp[i] | dp[i - 1] << j * j;
sum = sum + j * j;
}
}
cout << dp[n].count() << endl;
return 0;
}


浙公网安备 33010602011771号