lg 10000 が充分小さいことに着目して、メモ化する。
メモを long long int で持つとメモリで落ちた。
const int N = 5;
vector<int> num[N];
const int L = 26;
int memo[L][L][L][L][L];
const int mod = 1000000007;
int idx[N];
int rec(void)
{
int &ret = memo[idx[0]][idx[1]][idx[2]][idx[3]][idx[4]];
if (ret != -1) return ret;
lli sum = 0;
for (int i = 0; i < N; ++i) {
int j = (i + 1) % N;
if (num[i][idx[i]]) ; else continue;
if (num[j][idx[j]]) ; else continue;
const int a = idx[i], b = idx[j];
int n = num[i][idx[i]], m = num[j][idx[j]];
if (n % 2 && m % 2) {
idx[i] = max(idx[i] - 1, 0);
idx[j] = max(idx[j] - 1, 0);
sum = (sum + (lli)rec()) % mod;
}
idx[i] = distance(num[i].begin(), lower_bound(num[i].begin(), num[i].end(), n / 2));
idx[j] = distance(num[j].begin(), lower_bound(num[j].begin(), num[j].end(), m / 2));
sum = (sum + (lli)rec()) % mod;
idx[i] = a;
idx[j] = b;
}
return ret = sum;
}
class EllysFiveFriends {
public:
int getZero(vector <int> ns)
{
fill(num, num + 5, vector<int>());
for (int i = 0; i < N; ++i) {
num[i].push_back(ns[i]);
while (num[i].back()) {
int n = num[i].back();
if (n % 2) num[i].push_back(n - 1);
else num[i].push_back(n / 2);
}
reverse(num[i].begin(), num[i].end());
}
for (int i = 0; i < N; ++i) {
idx[i] = (int)num[i].size() - 1;
}
fill(&memo[0][0][0][0][0], &memo[L - 1][L - 1][L - 1][L - 1][L], -1);
memo[0][0][0][0][0] = 1;
return rec();
}
};
0 件のコメント :
コメントを投稿