結果
| 問題 |
No.1106 🦉 何事もバランスが大事
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2018-12-15 17:24:27 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 4 ms / 2,000 ms |
| コード長 | 2,170 bytes |
| コンパイル時間 | 1,185 ms |
| コンパイル使用メモリ | 101,036 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-11-23 18:27:52 |
| 合計ジャッジ時間 | 3,061 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 77 |
ソースコード
#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
using i64 = int64_t;
vector<int> conv(i64 x, int base) {
assert(base % 2 == 1);
vector<int> v;
while(x != 0) {
int rem = static_cast<int>(x % base);
if(rem > base / 2) { rem -= base; }
v.push_back(rem);
x -= rem;
assert(x % base == 0);
x /= base;
}
reverse(v.begin(), v.end());
return v;
}
int cmp(int x, int y) {
if(x < y) { return 0; }
if(x == y) { return 1; }
return 2;
}
// 下から
i64 f(i64 x) {
vector<int> a = conv(x, 5);
int n = static_cast<int>(a.size());
// dp[未満/丁度/超過][先行ゼロを除く一番左の桁の数字が正か][荷物側の分銅数][反対側の分銅数] := パターン数
vector<vector<vector<vector<i64>>>> dp(3, vector<vector<vector<i64>>>(2, vector<vector<i64>>(n+1, vector<i64>(n+1, 0))));
dp[1][0][0][0] = 1;
for(int i=n-1; i>=0; --i) {
vector<vector<vector<vector<i64>>>> ndp(3, vector<vector<vector<i64>>>(2, vector<vector<i64>>(n+1, vector<i64>(n+1, 0))));
for(int state=0; state<3; ++state) {
for(int leftmost=0; leftmost<2; ++leftmost) {
for(int cntM=0; cntM<=n; ++cntM) {
for(int cntP=0; cntP<=n; ++cntP) {
if(!dp[state][leftmost][cntM][cntP]) { continue; }
for(int d=-2; d<=2; ++d) {
int nstate = cmp(d, a[i]);
if(nstate == 1) { nstate = state; }
int nleftmost = d == 0 ? leftmost : d > 0,
ncntM = cntM + (d < 0 ? -d : 0),
ncntP = cntP + (d > 0 ? d : 0);
if(ncntM > n) { continue; }
if(ncntP > n) { continue; }
ndp[nstate][nleftmost][ncntM][ncntP] += dp[state][leftmost][cntM][cntP];
}
}
}
}
}
dp = ndp;
}
i64 res = 0;
for(int state=0; state<2; ++state) {
for(int cnt=1; cnt<=n; ++cnt) {
res += dp[state][1][cnt][cnt];
}
}
return res;
}
int main(void) {
i64 N; scanf("%ld", &N);
assert(1 <= N && N <= static_cast<i64>(powl(10, 18)));
i64 res = f(N);
printf("%ld\n", res);
return 0;
}