[记忆化搜索]vijos 1599 货币

背景

又是一道水题

描述

在某个神秘的星球上有一种货币,它有一种奇怪的兑换规则
你有且仅有一枚面值为n的金币,你可以去银行进行兑换,也可以不兑换
如果去银行兑换,兑换的规则是这样的:用面值为a的金币去兑换可以换到a/2,a/3,a/4这三枚硬币(如果
是小数则截尾取整),你可以兑换多次
读入n
输出你最后最多能拥有的钱数w
每个测试点中有T组数据

格式

输入格式

一个数T表示该点的测试数据组数(1=<T<=20 )
下面跟着T行,每行一个整数n(0 <= n <= 1000000000 )

输出格式

输出T行(一一对应)
每行一个整数就是你最后最多拥有的钱数w

样例1

样例输入1[复制]

2
12
2

样例输出1[复制]

13
2

限制

各个测试点3s

提示

小心数据较大,但是不需要高精度

思路:

记忆化搜索,数据比较大

代码:

#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
using namespace std;

typedef map<int, int> mii;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef long long LL;

const int N = 40000000;
LL f[N];
int ans;
LL dp(LL x)
{
    LL Max;
    if(x <= 11)
    {
        f[x] = x;
        return f[x];
    }
    if(x < 40000000 && f[x])//注意数组越界
        return f[x];
    Max = max(x, dp(x/2)+dp(x/3)+dp(x/4));
    if(x < 40000000)
    {
        f[x] = Max;
        return f[x];
    }
    return Max;
}
int main()
{
    int t;
    LL n;

    scanf("%d", &t);
    while(t-->0)
    {
        scanf("%I64d", &n);
        printf("%I64d\n", dp(n));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值