n 個人,每人 ID 為正整數。x>0)。dp[i][j]:前 `i` 人,第一組數位根為 `j` 的方案數。
轉移:`dp[i][j] = dp[i-1][j] + dp[i-1][(j - dr(id_i) + 9)%9]`。
空間優化:滾動數組 O(9)。
最終答案 = `dp[n][A] + dp[n][B]`(注意 `A==B` 時不重複)。
#include
using namespace std;
const int MOD = 258280327;
int dr(int x) { return (x-1)%9 + 1; }
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T; cin >> T;
while (T--) {
int n, A, B; cin >> n >> A >> B;
vector a(n);
int sum = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
a[i] = dr(a[i]);
sum += a[i];
}
sum = dr(sum);
int target = dr(A + B);
if (sum != target) {
int ans = 0;
if (sum == A) ++ans;
if (sum == B) ++ans;
cout << ans % MOD << "\n";
continue;
}
vector dp(10), ndp(10);
dp[a[0]] = 1;
for (int i = 1; i < n; ++i) {
fill(ndp.begin(), ndp.end(), 0);
for (int j = 1; j <= 9; ++j) {
int k = (j - a[i] + 9) % 9; if (k == 0) k = 9;
ndp[j] = (dp[j] + dp[k]) % MOD;
}
dp.swap(ndp);
}
int ans = (dp[A] + dp[B]) % MOD;
cout << ans << "\n";
}
return 0;
}
O(n × 9),n ≤ 1e5 極快。O(1)。