若是至少有一組解,則要 \(y\) 被 \(x\) 整除,也就是說 \(a_i\) 必定是 \(x\) 的倍數,可設 \(dp[i]\) 爲 和爲 \(i\) 且 \(gcd = 1\) 時的方案數,首先呢,若是不考慮 \(gcd\) 的限制,能夠發現,\(dp[i]=1<<(i-1)\) ,那麼咱們只要減去那些 \(gcd > 1\) 的方案數,枚舉因子就行了,記憶化搜索便可。c++
#include <bits/stdc++.h> using namespace std; const int MOD = 1e9 + 7; long long p2(int x) { long long a = 1, k = 2; while (x) { if (x & 1) a = a * k % MOD; k = k * k % MOD; x >>= 1; } return a; } map<int, long long> dp; long long dfs(int x) { if (dp.count(x)) return dp[x]; long long res = p2(x - 1); for (int i = 1; i * i <= x; i++) { if (x % i == 0) { if (i != 1) { res = (res - dfs(x / i) + MOD) % MOD; } if(i * i != x) res = (res - dfs(i) + MOD) % MOD; } } return dp[x] = res; } int main() { dp[1] = 1; int x, y, n; long long ans = 0; cin >> x >> y; if (y % x == 0) { ans = dfs(y / x); } cout << ans << endl; return 0; }
\(dp[i]\) 表示從 \(i\) 開始(\(s[i...n-1]\))所能構成的不相交 \(t\) 串的最多個數,並維護最小花費 \(mn[i]\) 。spa
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; string s; int dp[N], mn[N], ab[N]; int main() { int n, m, k = 0; cin >> n >> s >> m; for (int i = n - 1; i >= 0; i--) { if(s[i] == '?') k++; if(s[i] == '?' || s[i] == 'a') { if(s[i + 1] == 'b' || s[i + 1] == '?') ab[i] = ab[i + 2] + 2; else ab[i] = 1; } if(n - i >= m) { dp[i] = dp[i + 1]; mn[i] = mn[i + 1]; if(ab[i] >= m) { if(dp[i + m] + 1 > dp[i]) { dp[i] = dp[i + m] + 1; mn[i] = mn[i + m] + k; } else if(dp[i + m] + 1 == dp[i]) { mn[i] = min(mn[i], mn[i + m] + k); } } if(s[i + m - 1] == '?') k--; } } cout << mn[0] << endl; return 0; }