zoukankan      html  css  js  c++  java
  • POJ2486

    题目大意

    给定一棵n个结点的树,每个结点上有一定数量的苹果,你可以从结点1开始走k步(从某个结点走到相邻的结点算一步),经过的结点上的苹果都可以吃掉,问你最多能够吃到多少苹果?

    题解

    蛋疼的问题就是可以往回走~~~~想N就木有想到解法,看了下网上的解题报告~~~~想到了其实还是挺容易理解的~~~分为两种情况,就是有些点只需要走一次,而有些则需要走两次。

    方程表示:

    dp[0][u][j]表示从结点u开始走j步并且返回到结点u获得的最大价值

    dp[1][u][j]表示从结点u开始走j步不回到结点u获得的最大值

    dp[0][u][j]=max(dp[0][u][j],dp[0][u][j-k-2]+dp[0][v][k])(子节点v走完k步之后返回v,边(u,v)走了两次,所以其他子树需要走j-k-2步,并且也返回)

    dp[1][u][j]=max(dp[1][u][j],dp[1][u][j-k-2]+dp[0][v][k])(子树v走完k步返回结点u,同样,边(u,v)走了两次,所以其他子树也需要走j-k-2步,不返回)

    dp[1][u][j]=max(dp[1][u][j],dp[0][u][j-k-1]+dp[1][v][k])(先从结点u开始在除子树v外其他的子树走j-k-1步并且返回,边(u,v)只需要走一次,然后再在子树v走k步,不返回)

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    using namespace std;
    #define MAXN 105
    vector<int> G[MAXN];
    int dp[2][MAXN][MAXN*2],value[MAXN];
    int n,m;
    void dfs(int u,int fa)
    {
        for(int i=0;i<=m;i++) 
        {
            dp[0][u][i]=dp[1][u][i]=value[u];
        }
        for(size_t i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(fa==v) continue;
            dfs(v,u);
            for(int j=m-1;j>=0;j--)
            {
                for(int k=0;k<=j;k++)
                {
                    dp[0][u][j+2]=max(dp[0][u][j+2],dp[0][u][j-k]+dp[0][v][k]);
                    dp[1][u][j+2]=max(dp[1][u][j+2],dp[1][u][j-k]+dp[0][v][k]);
                    dp[1][u][j+1]=max(dp[1][u][j+1],dp[0][u][j-k]+dp[1][v][k]);
                }
            }
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=1;i<=n;i++) 
                scanf("%d",&value[i]);
            for(int i=0;i<MAXN;i++) G[i].clear();
                memset(dp,0,sizeof(dp));
            for(int i=1;i<n;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            dfs(1,-1);
            printf("%d
    ",max(dp[0][1][m],dp[1][1][m]));
        }
        return 0;
    }

              

  • 相关阅读:
    python 抓取网页
    Vim XDebug调试PHP php远程调试
    10 条 nmap 技巧
    Linux修改文件及文件夹权限
    mysql 常用命令 汇总
    VS2010打开过多的IntelliTrace.exe进程导致虚拟内存不足的解决办法
    黄聪:MYSQL远程连接失败:ERROR 1130: mysql 1130连接错误的有效解決方法
    黄聪:WordPress搬家更换域名教程
    黄聪:使用 ALinq 实现 Linq to MySQL【转】
    黄聪:Filezilla 二进制上传设定
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3434706.html
Copyright © 2011-2022 走看看