• POJ 2486 Apple Tree


    题目意思:一个N 个节点的苹果树,每个节点有一定数目的苹果;问从1 出发走K步 所能迟到的苹果(每一步只可以到相邻的节点)

      解法:

      走法包含以下基本的情况(其他的走法都可以由以下的组合出来):

      1:在树上头也不回的往前;

      2:回到走过的节点再去别的节点:

      所以对于每个节点有一个 flag 走了没回来?还是走过又回来了 !

    其他的就是背包的只是了依赖性的01背包么!

      dp[flag][i][j]// 节点I的子树内走J步 flag=1 代表没回到I,flag=0 代表回到了I

      dp[0][s][i+2]=max(dp[0][s][i+2],dp[0][s][j]+dp[0][tmp.to][i-j]);// 经由新的子树在回来所以要+2
      dp[1][s][i+2]=max(dp[1][s][i+2],dp[1][s][j]+dp[0][tmp.to][i-j]);// 经由新的子树再回来,且进入原来的树,所以要加2
      dp[1][s][i+1]=max(dp[1][s][i+1],dp[0][s][j]+dp[1][tmp.to][i-j]);// 经由原来的树,进入新的数,+1
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    const int maxn=105;
    const int INF=0x3fffffff;
    struct Edge
    {
        int to,dis,pre;
        Edge(int to=0,int dis=0,int pre=0):to(to),dis(dis),pre(pre){}
    };
    Edge edge[maxn];
    int head[maxn],pos;
    int dp[2][maxn][205];
    int num[maxn];
    int N,K;
    void inint()
    {
        memset(head,-1,sizeof(head));
        pos=0;
    }
    void add_edge(int s,int to,int dis)
    {
        edge[pos]=Edge(to,dis,head[s]);
        head[s]=pos++;
    }
    void dfs(int pa,int s)
    {
    
        for(int i=0;i<=K;i++)
            dp[0][s][i]=dp[1][s][i]=num[s];
        for(int w=head[s];~w;w=edge[w].pre)
        {
    
            Edge &tmp=edge[w];
            if(tmp.to==pa)continue;
            dfs(s,tmp.to);
            for(int i=K;i>=0;i--)
            {
                for(int j=0;j<=i;j++)
                {
                    dp[0][s][i+2]=max(dp[0][s][i+2],dp[0][s][j]+dp[0][tmp.to][i-j]);
                    dp[1][s][i+2]=max(dp[1][s][i+2],dp[1][s][j]+dp[0][tmp.to][i-j]);
                    dp[1][s][i+1]=max(dp[1][s][i+1],dp[0][s][j]+dp[1][tmp.to][i-j]);
                }
            }
        }
    }
    int main()
    {
        int a,b;
        while(~scanf("%d%d",&N,&K))
        {
            inint();
            for(int i=1;i<=N;i++)scanf("%d",&num[i]);
            for(int i=2;i<=N;i++)
            {
                scanf("%d%d",&a,&b);
                add_edge(a,b,1);
                add_edge(b,a,1);
            }
            dfs(-1,1);
            printf("%d
    ",dp[1][1][K]);
        }
        return 0;
    }
     
  • 相关阅读:
    forward redirect 区别
    request response 区别
    Java集合 初步了解
    通过session统计当前在线人数
    Session保存用户名到Session域对象中
    Cookie获取用户的访问记录
    表单中有关于爱好的多选框, 篮球,足球,游泳,跑步, 再有一个多选框,代表全选
    jQuery常用子元素过滤选择器
    jQuery常用属性过滤选择器
    jQuery常见可见性过滤选择器
  • 原文地址:https://www.cnblogs.com/shuly/p/3877360.html
Copyright © 2020-2023  润新知