简单瞎搞题
可以发现这题只存在两种状态0或者1,这种单一状态状态压缩动态规划的可以通过STL中的bitset去优化内存。
比较容易发现当前状态一定可以通过前面一个状态转移过来,阶段的话可以选择在 中的某个数据算平方。累加进当前状态
具体实现就是,先处理第一次输入的数据,保证不全是0(其实按照0初始化为1,去推进好像也可以)。
后面开一个副本,把原先的可以得到的答案,左移 进行或运算,把全部新平方值进行更新。
这里如果直接或等于会重复计算,不能直接的通过一个bitset去更新。
比如01101,表示1,3,4可以算到,<<1只后11010,表示2,4,5可以算到。
很多bitset地方都要注意这一条,别把当前的状态更新累加到当前状态前一个过程中去了,这样算出来往往会多一些不正确的答案。
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; inline int read() { int s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } const int N = 105; bitset<N * N * N> ans, tmp; //100个100的平方相加 int main() { int n = read(); int l = read(), r = read(); for (int i = l; i <= r; ++i) ans[i * i] = 1; for (int i = 2; i <= n; ++i) { int l = read(), r = read(); tmp.reset(); //清0 for (int j = l; j <= r; ++j) tmp |= ans << j * j; ans = tmp; } printf("%d\n", ans.count()); return 0; }