P7961 [NOIP2021] 数列 (DP 刷表法)

(n<=30,是个多维的DP)

v数组就是用来计算权值的,一共有m+1个。将S看做一个二进制数,按照题目S的定义,相当于在S的每一位可以随便+1(满足限制情况下),一共可以加n次。

我们来建立DP的维度,首先第一个i表示对二进制数处理到i位(从低位到高位),j表示使用了几个数(一共n个数可使用),为了满足题目要求,我们还要设置一个k表示此时的二进制一共有多少个1(题目要求不超过K),可能还会有进位的情况,再加一个p表示要向下一位进位的个数。

于是就有f[i][j][k][p](表示这四维状态下的权值和),如果用填表法不好处理,那就用刷表法向后转移:

已经选了j个数,还剩下n-j个数,我们从剩下数中选择t个加入到i+1位,再处理一下进位的情况,就有f[i+1][j+t][k+(t+p)mod2][(t+p)>>1]+=f[i][j][k][p]*pv[i][t]*C[n-j][t]。pv和C在代码中均有解释。

处理完后最高位可能还有进位的情况,再简单的处理一下就行了。

 1 #include<bits/stdc++.h>
 2 #define mod 998244353
 3 #define ll long long
 4 using namespace std;
 5 ll ans, f[105][35][35][16], C[35][35], v[105], pv[105][35];
 6 
 7 void init(int n) {//预处理组合数 
 8     for (int i = 0; i <= n; i++) C[i][0] = 1;
 9     for (int i = 1; i <= n; i++) 
10         for (int j = 1; j <= i; j++) 
11             C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
12 }
13 
14 int popcnt(int n) {//统计二进制下1的个数 
15     int res = 0;
16     while (n) res += n & 1, n >>= 1;
17     return res;
18 }
19 
20 int main() {
21     init(30);
22     int n, m, K;
23     scanf("%d %d %d", &n, &m, &K);
24     for (int i = 0; i <= m; i++) {
25         scanf("%lld", &v[i]);
26         pv[i][0] = 1;
27         for (int j = 1; j <= n; j++) pv[i][j] = pv[i][j - 1] * v[i] % mod;//i^j
28     }
29     f[0][0][0][0] = 1;
30     for (int i = 0; i <= m; i++)
31         for (int j = 0; j <= n; j++)
32             for (int k = 0; k <= K; k++)
33                 for (int p = 0; p <= n >> 1; p++)
34                     for (int t = 0; t <= n - j; t++) {
35                         f[i + 1][j + t][k + (t + p & 1)][(t + p) >> 1] = (f[i + 1][j + t][k + (t + p & 1)][(t + p) >> 1] + f[i][j][k][p] * pv[i][t] % mod * C[n - j][t] % mod) % mod;                                      
36                     }
37     for (int k = 0; k <= K; k++) 
38         for (int p = 0; p <= n >> 1; p++)
39             if (k + popcnt(p) <= K) 
40                 ans = (ans + f[m + 1][n][k][p]) % mod;
41     printf("%lld\n", ans);
42     return 0;                    
43 }

 

posted @ 2022-07-25 11:59  YHXo  阅读(76)  评论(0编辑  收藏  举报