zoukankan      html  css  js  c++  java
  • POJ Apple Tree 题解(树形dp+01背包)

    题目链接

    题目大意

    有一个树,n个节点,第一个节点为根节点,每个点都有一个权值,每个点都可以移动到相邻的点,给你树的连接情况,求出,走k步最多获得多少权值?

    题目思路

    主要考虑回头的情况,所以不能简单的设置(dp[i][j])

    (dp[i][j][0])表示在子树 i中最多走 j步最后还回到 i 能得到的最大苹果数。
    (dp[i][j][1]) 表示在子树 i中最多走 j步最后不回到 i 能得到的最大苹果数

    然后再跑01背包即可

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=2e2+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-6;
    int n,k;
    int a[maxn];
    int dp[maxn][maxn][2];
    vector<int> g[maxn];
    void dfs(int u,int fa){
        for(int i=0;i<=k;i++){
            dp[u][i][0]=dp[u][i][1]=a[u];
        }
        for(int a=0;a<g[u].size();a++){
            int x=g[u][a];
            if(x==fa) continue;
            dfs(x,u);
            for(int i=k;i>=1;i--){
                for(int j=0;j<=i;j++){
                    if(i-j-2>=0)  dp[u][i][0]=max(dp[u][i][0],dp[x][j][0]+dp[u][i-j-2][0]);
                    if(i-j-1>=0)  dp[u][i][1]=max(dp[u][i][1],dp[x][j][1]+dp[u][i-j-1][0]);
                    if(i-j-2>=0)  dp[u][i][1]=max(dp[u][i][1],dp[x][j][0]+dp[u][i-j-2][1]);
                }
            }
        }
    }
    signed main(){
        while(scanf("%d%d",&n,&k)!=-1){
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                g[i].clear();
                for(int j=0;j<=k;j++){
                    dp[i][j][0]=dp[i][j][1]=0;
                }
            }
            for(int i=1,u,v;i<=n-1;i++){
                scanf("%d%d",&u,&v);
                g[u].push_back(v);
                g[v].push_back(u);
            }
            dfs(1,-1);
            int ans=0;
            ans=max(ans,dp[1][k][0]);
            ans=max(ans,dp[1][k][1]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    Android 编辑框(EditText)属性学习
    读书笔记 -《高效程序猿的45个习惯-敏捷开发修炼之道》
    Launcher3实现壁纸居中
    Trie树的常见应用大总结(面试+附代码实现)
    LeetCode Summary Ranges
    abap选择屏幕上的button
    SQLite Expert表分离和解决SQLite Expert删除表后大小不变的问题
    git push 失败
    动态限制EdiText仅仅能输入特定字符
    DateTime类常用技巧摘录
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15177594.html
Copyright © 2011-2022 走看看