1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <cmath> #include <iostream> #include <map> #include <vector>
using namespace std; using ll = long long;
ll backtracking(const vector<ll> &A, const vector<ll> &B, const vector<ll> &suffixA, const vector<ll> &suffixB, ll needA, ll needB, ll position, map<tuple<ll, ll, ll>, ll> &memo, map<tuple<ll, ll>, ll> &memoA, map<tuple<ll, ll>, ll> &memoB) { const ll n = A.size(); if (position >= n) { return needA <= 0 && needB <= 0 ? 1 : 0; } auto it = memo.find({needA, needB, position}); if (it != memo.end()) { return it->second; } if (needA <= 0 && needB <= 0) { return memo[{needA, needB, position}] = pow(3, n - position); } if (needA > suffixA[position] || needB > suffixB[position]) { return memo[{needA, needB, position}] = 0; } if (needA <= 0) { auto it = memoA.find({needB, position}); if (it != memoA.end()) { return it->second; } } if (needA <= 0) { auto it = memoA.find({needB, position}); if (it != memoA.end()) { return it->second; } } if (needB <= 0) { auto it = memoB.find({needA, position}); if (it != memoB.end()) { return it->second; } } ll ret = 0; ret += backtracking(A, B, suffixA, suffixB, needA - A[position], needB - B[position], position + 1, memo, memoA, memoB); ret += backtracking(A, B, suffixA, suffixB, needA, needB - B[position], position + 1, memo, memoA, memoB); ret += backtracking(A, B, suffixA, suffixB, needA - A[position], needB, position + 1, memo, memoA, memoB); if (needA <= 0) { memoA[{needB, position}] = ret; } if (needB <= 0) { memoB[{needA, position}] = ret; } return memo[{needA, needB, position}] = ret; }
int main() { ll T; cin >> T; for (ll iCase = 1; iCase <= T; ++iCase) { ll N, H; cin >> N >> H; vector<ll> A(N), B(N), suffixA(N), suffixB(N); for (int i = 0; i < N; ++i) { cin >> A[i]; } for (int i = 0; i < N; ++i) { cin >> B[i]; } if (N > 0) { suffixA[N - 1] = A[N - 1]; suffixB[N - 1] = B[N - 1]; } for (int i = N - 2; i >= 0; --i) { suffixA[i] = A[i] + suffixA[i + 1]; suffixB[i] = B[i] + suffixB[i + 1]; } map<tuple<ll, ll, ll>, ll> memo; map<tuple<ll, ll>, ll> memoA; map<tuple<ll, ll>, ll> memoB; auto ans = backtracking(A, B, suffixA, suffixB, H, H, 0, memo, memoA, memoB);
cout << "Case #" << iCase << ": " << ans << endl; } }
|