洛谷P1270_树形dp_dfs+记忆化搜索

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1000;

struct treenode
{
    int time, val;
}tn[maxn*10];

int pt;//警察到达的时间
int dp[maxn][maxn]={0};//在i节点,剩余时间为j的最大值(只管当下)

int dfs(int rt, int tt);
void gettree(int rt);

int main()
{
    scanf("%d", &pt);
    gettree(1);
    int ans = dfs(1, pt-1);
    printf("%d\n", ans);
    return 0;
}

int dfs(int rt, int tt)//树的节点,当前剩余时间, 记忆化搜索
{
    if(dp[rt][tt] || !tt) return dp[rt][tt];//记忆化!!
    int tmpt = tt - tn[rt].time;
    if(tn[rt].val && tmpt) return dp[rt][tt] = min(tn[rt].val, tmpt/5);
    for(int i = 0; i <= tmpt; ++i)//枚举两边子树的时间
    {
        int tmp = dfs(rt<<1, i)+dfs(rt<<1|1, tmpt-i);
        dp[rt][tt] = max(dp[rt][tt], tmp);
    }
    return dp[rt][tt];
}

void gettree(int rt)
{
    int t, v;
    scanf("%d %d", &t, &v);
    tn[rt].time = t*2;
    tn[rt].val = v;
    if(v) return;
    gettree(rt<<1);
    gettree(rt<<1|1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值