传送门;牛客
题目描述:
一共有 n个数,第 i 个数是 xi
xi 可以取
[
l
i
,
r
i
]
[li , ri]
[li,ri] 中任意的一个值。
设
S
=
∑
x
i
2
S = \sum{{x_i}^2}
S=∑xi2
,求 S 种类数。
输入:
5
1 2
2 3
3 4
4 5
5 6
输出:
26
这道题目还是挺有意思的.首先我们看到这道题目想到的应该是区间dp的想法
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;
}
b
t
i
s
e
t
<
l
e
n
g
t
h
>
d
p
[
100
]
btiset
d
p
[
0
]
.
s
e
t
(
0
)
:
代表将我们的第一个
01
串的第
0
个位置置为
1
dp[0].set(0):代表将我们的第一个01串的第0个位置置为1
dp[0].set(0):代表将我们的第一个01串的第0个位置置为1
(注意我们的bitset是从右往左进行移动的)
d
p
[
n
]
.
c
o
u
n
t
(
)
,
用来输出我们的
01
串中的
1
的个数
dp[n].count(),用来输出我们的01串中的1的个数
dp[n].count(),用来输出我们的01串中的1的个数在本题中就是不同数字的是否可行性
下面是具体的代码部分:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
ll x=0,w=1;char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*w;
}
#define maxn 1000010
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
int n;
bitset<maxn>dp[110];
int main() {
n=read();int l,r;
dp[0].set(0);
for(int i=1;i<=n;i++) {
l=read();r=read();
for(int j=l;j<=r;j++) {
dp[i]|=(dp[i-1]<<(j*j));
}
}
cout<<dp[n].count()<<endl;
return 0;
}