NOIP 2021 题解(更新中)

T1 报数

很智障的题,筛一遍就行了

唯一要注意的就是要筛到 $10^7+1 $,因为对于9999998,输出应该是 \(10^7+1\)

代码想必是没必要贴了

T2 数列

题面有点小绕,大概是拼一个二进制数出来,满足1的个数小于k,还要求个权值和

考虑用计数dp

题目中提到 \(S=2^{a_1}+2^{a_2}+...+2^{a_m}\)

可以看出,在取\(a_i\)时,对于答案的贡献为\(v_{a_i}\)

\(S\)的定义式,很容易联想到\(S\)其实是\(m\)个头部为\(1\)剩余为\(0\)的二进制数的和

像这样

那么我们就可以考虑把这个问题转化成在\(1 - m\)这些位置,标上共n个\(1\)(每个位置可以标多个),我们明显感受到这个问题可以考虑dp

然后我们考虑dp的状态

\(令dp[i][j][l][p]表示当前正在第i个位置,已经选取了j个1,合成的S中共有l个1,前一位向本位进位 p 时序列的权值和\)

接下来推转移方程。

若我们现在在位置\(i\)上,想要推出\(i+1\)的权值。

假设我们要在当前位置上选取\(q\)\(1\),显然目标状态为$ dp[i+1][j+q][l+(p+q)%2)$ $] $ $ [$ $ (p+q)/2 $ \(]\)

转移系数呢?首先考虑\(v_i\)的贡献值,即先乘上一个\(v_i^q\);接下来,考虑排列形成的不同情况,做转移时我们总共有\(n-j\)个空位可供选取,从中选\(q\)个,显而易见是\(C(q,n-j)\)

得到转移方程
\(dp[i+1][j+q][l+(p+q)\) % \(2][(p+q)/2]=dp[i][j][l][p]*v_i^q*C(q,n-j)\)

统计答案时,显然所有答案存在$ dp[m+1][n][l][p] $中,我们只需\(0 - k\)地枚举\(l\)\(0-n\)地枚举\(p\),若\(l+popcnt(p)<=k\),就将\(dp[m+1][n][l][p]\)加进总答案

当然,组合数和popcnt是可以预处理的,如果转移的时候暴算会T掉

posted @ 2022-06-10 21:18  羊扬羊  阅读(185)  评论(0编辑  收藏  举报