zoukankan      html  css  js  c++  java
  • POJ 2486 Apple Tree

    题目大意:

    一棵树上每个节点都有几个苹果。问在根节点出发,走不大于K步的情况下最多能取多少个苹果。


    解题思路:

    树形DP,对于每个子树的根节点src,都有dp[src][i][0],表示从src走i步可以回到src最多可以得到多少苹果。dp[src][i][1]表示从src走i步没有回到src最多可以得到多少苹果。

    状态有三种转移方式:
    1、用i-j-2步走其它子树回到根节点再用j步走某一子树再回到根节点。

    2、用i-j-2步走其它子树回到根节点再用j步走某一子树没有回到根节点。

    3、用j步走某一子树再回到根节点在用i-j-1步走其它子树不回到根节点。


    注意状态的初始化。


    以下是代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #include <math.h>
    #include <stdlib.h>
    #include <vector>
    #include <string>
    #include <map>
    #include <queue>
    using namespace std;
    
    int min(int a,int b)
    {
        if(a>b)a=b;
        return a;
    }
    int max(int a,int b)
    {
        if(a<b)a=b;
        return a;
    }
    struct node1
    {
        int to,next;
    }edge[105*2];
    int head[105],cnt,n,k,applenum[105],u,v,dp[105][205][2];
    bool vis[105];
    void addedge(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
        edge[cnt].to=u;
        edge[cnt].next=head[v];
        head[v]=cnt++;
    }
    bool chack(int src)
    {
        int t=head[src];
        while(t!=-1)
        {
            if(!vis[edge[t].to])return true;
            t=edge[t].next;
        }
        return false;
    }
    void dfs(int src)
    {
        if(vis[src])return;
        else vis[src]=true;
        if(chack(src))
        {
            int t=head[src];
            while(t!=-1)
            {
                if(vis[edge[t].to])
                {
                    t=edge[t].next;
                    continue;
                }
                dfs(edge[t].to);
                for(int i=k;i>0;i--)
                {
                    for(int j=0;i-j>=0;j++)
                    {
                        if(i-j-2>=0)
                        {
                            dp[src][i][0]=max(dp[src][i][0],dp[src][i-j-2][0]+dp[edge[t].to][j][0]);
                            dp[src][i][1]=max(dp[src][i][1],dp[src][i-j-2][1]+dp[edge[t].to][j][0]);
                        }
                        if(i-j-1>=0)
                        {
                            dp[src][i][1]=max(dp[src][i][1],dp[src][i-j-1][0]+dp[edge[t].to][j][1]);
                        }
                    }
                }
                t=edge[t].next;
            }
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            cnt=0;
            memset(vis,false,sizeof(vis));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                head[i]=-1;
                scanf("%d",&applenum[i]);
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<=k;j++)
                {
                    dp[i][j][0]=applenum[i];
                    dp[i][j][1]=applenum[i];
                }
            }
            for(int i=2;i<=n;i++)
            {
                scanf("%d%d",&u,&v);
                addedge(u,v);
            }
            dfs(1);
            printf("%d
    ",max(dp[1][k][0],dp[1][k][1]));
        }
        return 0;
    }
    


  • 相关阅读:
    根据痛点分析制作软件
    大学生三大痛点及分析
    统计作业
    蜜迹(个人项目设计)
    一款有趣的影子游戏《Shadowmatic-投影寻真》
    Java项目实战_疫情地图可视化_day03
    Java项目实战_疫情地图可视化_day02
    Java项目实战_疫情地图可视化_day01
    《敏捷软件开发原则,模式与实践》阅读笔记三
    《敏捷软件开发原则,模式与实践》阅读笔记二
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4239126.html
Copyright © 2011-2022 走看看