洛谷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);
}

猜你喜欢

转载自blog.csdn.net/jay__bryant/article/details/80216158