10月31日晚arc107真题
先吐槽这一场的前四题竟然都是计数题,让我非常震惊.
这是一道十分精巧的dp,对提高自身的dp实力有比较大的帮助,本人强烈推荐.
题意
求含有
n
n
n个数,和为
k
k
k,每个数都形如
1
2
i
(
i
∈
N
)
\frac{1}{2^i} (i\in N)
2i1(i∈N)的集合数量取模
998244353
998244353
998244353.
1
≤
k
≤
n
≤
3000
1\leq k\leq n\leq 3000
1≤k≤n≤3000.
dp状态寻求
符合条件的集合可以分为两种:
- 含有 1 1 1的集合
- 不含有 1 1 1的集合
假设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示
i
i
i个数组成
j
j
j的集合数量.
对于第一种情况,去掉一个
1
1
1,则答案可从
d
p
[
i
−
1
]
[
j
−
1
]
dp[i-1][j-1]
dp[i−1][j−1]转移过来.
对于第二种情况,集合内所有数都乘2,相当于从
d
p
[
i
]
[
j
×
2
]
dp[i][j\times 2]
dp[i][j×2]转移过来.
结束.
const int aoi=3058,mod=998244353;
ll dp[aoi][aoi];
int main() {
int i,j,n,k;
read(n),read(k);
for (**dp=i=1;i<=n;++i) {
for (j=i;j;--j)
dp[i][j]=(dp[i-1][j-1]+(j*2>i?0:dp[i][j*2]))%mod;
}
printf("%lld\n",dp[n][k]);
}
谢谢.