SPOJ系列 —— SPOJ346
SPOJ 346
#dynamic program
In
Byteland
they have a very strange monetary system.Each
Bytelandian
gold coin has an integer number written on it. A coin \(n\) can be exchanged in a bank into three coins:$ n/2$, \(n/3\) and \(n/4\). But these numbers are all rounded down (the banks have to make a profit).You can also sell
Bytelandian
coins forAmerican
dollars. The exchange rate is \(1:1\). But you can not buyBytelandian
coins.You have one gold coin. What is the maximum amount of
American
dollars you can get for it?(
0 <= n <= 1 000 000 000
)
这题实际上就是一个递推式:
但是由于n
很大,简单的递推会出现很多重复运算,又因为n
很大无法直接开这么大的数组,因此我们可以先预处理计算出n <= 1e5
的数据,并记忆化搜索这些数据即可。因此本题还算非常basic(of course, u can use map
or unordered_map
to maintain the value.)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e6 + 50;
ll dp[maxn];
ll helper(int cur){
if (cur < maxn && dp[cur] != -1) return dp[cur];
if (cur < 12) return dp[cur] = cur;
ll ans = helper(cur / 2) + helper(cur / 3) + helper(cur / 4);
if (cur < maxn) dp[cur] = ans;
return ans;
}
int main(){
memset(dp, -1, sizeof(dp));
int n;
while (std::cin >> n)
std::cout << helper(n) << "\n";
return 0;
}
/* SPOJ 346 Memo dp */
if u want use python to solve this problem, and u should deal with the I/O problem.
You can use the follow code to finish the function like while (std::cin >> n)
in C/C++
def rdi(): return int(input())
dp = {}
def f(x):
if (x < 12): return x
if (x in dp): return dp[x]
ans = f(x // 2) + f(x // 3) + f(x // 4)
dp[x] = ans
return ans
while True:
try:
n = rdi()
print(f(n))
except EOFError:
break