链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
一共有 n个数,第 i 个数是 xi
xi 可以取 [li , ri] 中任意的一个值。
设 S=∑xi^2,求 S 种类数。
输入描述:
第一行一个数 n。 然后 n 行,每行两个数表示 li,ri。
输出描述:
输出一行一个数表示答案。
示例1
输入
5 1 2 2 3 3 4 4 5 5 6
输出
26
题目分析
题目显然为分组背包,设f【i】【j】=0or1表示前i个数能否表示j;
转移为f【i】【j】=1仅当f【i-1】【j-x*x】=1时(x=【l【i】,r【i】】);
这样会枚举n,区间长度和j的值,即复杂度为1e10,超时...
这样其实比较浪费,f数组是一个只有01两个值的数组,于是可以考虑用bitset来优化它。
这样一行就可以一起求,如果用f【i】表示第i行的01串,那么有转移方程:
f【i】=f【i】| (f【i-1】<<(x【i】^2))。
代码
#include<bits/stdc++.h>
using namespace std;
bitset<1000010>f[110];
int l[110],r[110];
int main ()
{
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>l[i]>>r[i];
f[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=l[i];j<=r[i];j++)f[i]|=(f[i-1]<<j*j);
}
cout<<f[n].count();
return 0;
}