[NC17193]简单瞎搞题(bitset)

题目

NC17193

思路

先思考暴力做法,每组依次判断能否和桶里的数组成一个新的数,能则为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;
} 
posted @ 2021-08-02 10:11  行舟C  阅读(42)  评论(0)    收藏  举报