Description
给定
n
个数,求将这
Solution
11
的倍数的奇数位之和与偶数位之和之差为
11
的倍数。
把每个数记为奇数位之和与偶数位之和之差,那么如果他的第一位是奇数位,就相当于加上这个数,否则就是减掉这个数。
先考虑长度为奇数的数,可以
O(n2)
DP出有
i
个数第一位是奇数位,贡献为
在考虑把偶数插进去。
直接插就好了。
也是
O(n2)
的DP吧。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int MOD = 998244353;
const int N = 2020;
typedef long long ll;
inline char get(void) {
static char buf[100000], *S = buf, *T = buf;
if (S == T) {
T = (S = buf) + fread(buf, 1, 100000, stdin);
if (S == T) return EOF;
}
return *S++;
}
inline void read(int &x) {
static char c; x = 0;
for (c = get(); c < '0' || c > '9'; c = get());
for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
}
inline int readi(int &x) {
static char c; x = 0; int cnt = 1;
for (c = get(); c < '0' || c > '9'; c = get());
for (; c >= '0' && c <= '9'; c = get()) {
x += (c - '0') * cnt; cnt *= -1;
}
x = (x % 11 + 11) % 11;
return cnt;
}
int n, x, l1, l2, res, test;
int a[N], b[N], c[N];
int dp[N][12], dp1[N][12];
int ans;
inline int Mod(int x, int P) {
return (x % P + P) % P;
}
inline int Min(int a, int b) {
return a < b ? a : b;
}
int main(void) {
read(test);
while (test--) {
read(n); ans = 0; *c = *b = 0;
for (int i = 1; i <= n; i++) {
x = readi(a[i]);
if (~x) c[++*c] = a[i];
else b[++*b] = a[i];
}
l1 = (*b + 1) / 2; l2 = *b / 2;
memset(dp, 0, sizeof dp);
dp[0][0] = 1;
for (int i = 1; i <= *b; i++) {
for (int j = 0; j <= n; j++)
for (int k = 0; k < 11; k++) {
dp1[j][k] = dp[j][k];
dp[j][k] = 0;
}
for (int j = 0; j <= n; j++)
for (int k = 0; k < 11; k++) {
if (j) dp[j][k] += (ll)dp1[j - 1][Mod(k - b[i], 11)] * (l1 - j + 1) % MOD;
dp[j][k] += (ll)dp1[j][Mod(k + b[i], 11)] * (l2 - i + j + 1) % MOD;
dp[j][k] %= MOD;
}
}
for (int j = 0; j < l1; j++)
for (int k = 0; k < 11; k++)
dp[j][k] = 0;
for (int i = 1; i <= *c; i++) {
for (int j = 0; j <= n; j++)
for (int k = 0; k < 11; k++) {
dp1[j][k] = dp[j][k];
dp[j][k] = 0;
}
for (int j = 0; j <= n; j++)
for (int k = 0; k < 11; k++) {
if (j) dp[j][k] += (ll)dp1[j - 1][Mod(k + c[i], 11)] * (j - 1) % MOD;
dp[j][k] += (ll)dp1[j][Mod(k - c[i], 11)] * (i - j + *b) % MOD;
dp[j][k] %= MOD;
}
}
for (int i = 0; i <= n; i++)
ans = Mod(ans + dp[i][0], MOD);
cout << ans << endl;
}
return 0;
}