题意:
价值为n的硬币,可以换为价值为n / 2, n / 3, n / 4的三枚硬币。给出n,问最大硬币总和。
(n <= 1000000000)
设dp[i]表示价值为i的硬币可以获得的最大价值。显然有
dp[i] = max(i, dp[i / 2] + dp[i / 3] + dp[i / 4])
但是数组太大,于是先算出一段数值内的dp,大于这个数值的用搜索就好了。
#include <cstdio>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const int maxn = 5000005;
ULL dp[maxn];
ULL dfs(ULL x) {
if(x < maxn) return dp[x];
return max(x, dfs(x / 2) + dfs(x / 3) + dfs(x / 4));
}
int main() {
dp[0] = 0;
for(int i = 1; i < maxn; i++) dp[i] = max((ULL)i, dp[i / 2] + dp[i / 3] + dp[i / 4]);
ULL n;
while(scanf("%llu", &n) != EOF) printf("%llu\n", dfs(n));
return 0;
}