zoj 3626 Treasure Hunt I (树形dp)

题目大意:

给出一棵树,求出从起点开始走m长度最后回到起点,所能得到的宝藏的最大价值。

思路分析:

通过一次dfs可以得到的是子树到根节点的所有距离的最大值。

现在的问题就是他走完一颗子树可以去另外一颗子树。

所以在回溯到根的时候要统计其他子树上互补距离的最大值。

dp[i] [j] 表示i为根节点,在i的子树中走j步然后回到i所能拿到的最大价值。

转移方程就是

dp[x][i+2*len]=max(dp[x][i+2*len],dp[v][j]+dp[x][i-j]);

v为x的子树的根,len 为 x-v的距离

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstring>
#define maxn 105
using namespace std;

int dp[maxn][maxn<<1];
int val[maxn];
int n,m,k;

int tot;
int head[maxn];
int next[maxn<<1];
int to[maxn<<1];
int cost[maxn<<1];

void init()
{
    tot=0;
    memset(head,0,sizeof head);
}
void addedge(int u,int v,int w)
{
    tot++;
    next[tot]=head[u];
    to[tot]=v;
    cost[tot]=w;
    head[u]=tot;
}
bool vis[maxn];
void dfs(int x)
{
    for(int i=0;i<=m;i++)
        dp[x][i]=0;
    for(int p=head[x];p;p=next[p])
    {
        int v=to[p];
        if(vis[v])continue;
        int len=cost[p];
        vis[v]=true;
        dfs(v);
        for(int i=m;i>=0;i--)
        {
            if(i+2*len>m)continue;
            for(int j=0;j<i;j++)
                dp[x][i+2*len]=max(dp[x][i+2*len],dp[v][j]+dp[x][i-j]);
        }
        for(int i=len*2;i<=m;i++)
            dp[x][i]=max(dp[x][i],dp[v][i-len*2]);
    }
    for(int i=0;i<=m;i++)
        dp[x][i]+=val[x];
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        init();
        for(int i=1;i<=n;i++)scanf("%d",&val[i]);
        for(int i=2;i<=n;i++)
        {
            int l,r,w;
            scanf("%d%d%d",&l,&r,&w);
            addedge(l,r,w);
            addedge(r,l,w);
        }
        scanf("%d%d",&k,&m);
        memset(vis,false,sizeof vis);
        vis[k]=true;
        dfs(k);
        int ans=0;
        for(int i=0;i<=m;i++)
        {
            ans=max(ans,dp[k][i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

zoj 3626 Treasure Hunt I (树形dp)

时间: 2024-08-13 02:28:33

zoj 3626 Treasure Hunt I (树形dp)的相关文章

[zoj 3626]Treasure Hunt I 树DP

<span style="font-family: Arial, Helvetica, Verdana, sans-serif; background-color: rgb(255, 255, 255);">Treasure Hunt I</span> Time Limit: 2 Seconds      Memory Limit: 65536 KB Akiba is a dangerous country since a bloodsucker living

ZOJ 3626 Treasure Hunt I(树形dp)

Treasure Hunt I Time Limit: 2 Seconds      Memory Limit: 65536 KB Akiba is a dangerous country since a bloodsucker living there. Sometimes the bloodsucker will appear and kill everyone who isn't at his hometown. One day, a brave person named CC finds

ZOJ-3626 Treasure Hunt I 树形DP

很久很久以前有一个吸血鬼,每m天就会出现一次,把不在自己村子呆着的冒险家吃掉.有n个村子,n-1条道路,每个村子都有一定数量的财富,默认探险家刚一到达一个村子就能获得财富,给出探险家的出生的村子和多少天后吸血鬼出现. 要求在吸血鬼出现之前赶回自己的村子,其实就是求一棵以k为根的各点权值之和最大且各边权加起来<=m/2的子树. #include <iostream> #include <cstdio> #include <cmath> #include <cs

zoj 3629 Treasure Hunt IV 打表找规律

H - Treasure Hunt IV Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a from b in

zoj 3629 Treasure Hunt IV(找规律)

Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a fromb in front of her.Alice was very excited but unfortunately not all of the treasures are real, some are fake.Now w

ZOJ 3201 Tree of Tree (树形DP)

题意:给定一棵树,求大小为k的一个子树的最大权值. 析:dp[i][j] 表示以 i 为根大小为 j 时最大权值.dp[i][j] = max{dp[i][j-k] + dp[son][k]},状态方程. 有一个要注意,因为要选的是一棵子树,所以以哪个点为根都行,也就是说,对于任意子树都能找一个合适的根,使得不会出现父结点与子结点冲突. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <

ZOJ 3627 Treasure Hunt II (贪心,模拟)

题意:有n个城市并排着,每个城市有些珠宝,有两个人站在第s个城市准备收集珠宝,两人可以各自行动,但两人之间的距离不能超过dis,而且每经过一个城市就需要消耗1天,他们仅有t天时间收集珠宝,问最多能收集多少珠宝? 思路: 其实就是类似一个滑动窗口在收集一个序列上的权值.首先两个人可以同时往两边散开,直到极限距离dis(这样省时),然后他们可能往左/右走,也可能往左走一会儿再往右走,也可能往右走一会儿再往左走.可以看出其实这些考虑都是对称的,那么我们主要考虑1边就行了.可以尝试枚举往左边走k天,其他

【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock&#39;s blog】

树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AVL树,线段树.SPLAY树,后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点.这里面的关键就是返回的信息部分,这个也没一般性的东西可讲

【树形dp】Treasure Hunt I

[ZOJ3626]Treasure Hunt I Time Limit: 2 Seconds      Memory Limit: 65536 KB Akiba is a dangerous country since a bloodsucker living there. Sometimes the bloodsucker will appear and kill everyone who isn't at his hometown. One day, a brave person named