zoukankan      html  css  js  c++  java
  • poj2486

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define MAXN 105
    using namespace std;
    
    int n,k,tot;
    int a[MAXN],h[MAXN];
    int f[MAXN][MAXN<<1][2];//那个子树,移动几次  是否回到根 
    
    struct node{
        int from,to,next;
    }e[MAXN<<1];
    
    void init(){
        tot=0;
        memset(h,-1,sizeof(h));
        memset(f,0,sizeof(f));
    }
    
    void add(int x,int y){
        tot++;
        e[tot].from=x;
        e[tot].to=y;
        e[tot].next=h[x];
        h[x]=tot;
    }
    //0表示回来根  1表示不必 
    int dfs(int now,int fa){
        for(int i=0;i<=k;i++)f[now][i][0]=f[now][i][1]=a[now];
        for(int i=h[now];i!=(-1);i=e[i].next){
            if(e[i].to!=fa){
            dfs(e[i].to,now);    
            //开始dp了喔    
                for(int j=k;j>=0;j--){
                    for(int p=1;p<=j;p++){
                        if(p>=2)f[now][j][0]=max(f[now][j][0],f[now][j-p][0]+f[e[i].to][p-2][0]);
                        if(p>=1)f[now][j][1]=max(f[now][j][1],f[now][j-p][0]+f[e[i].to][p-1][1]);
                        if(p>=2)f[now][j][1]=max(f[now][j][1],f[now][j-p][1]+f[e[i].to][p-2][0]);
                    }
                }            
            }
        }
    } 
    
    int main(){
        while(scanf("%d%d",&n,&k)==2){
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            init();
            for(int i=1;i<n;i++){
                int x,y;scanf("%d%d",&x,&y);
                add(x,y);
                add(y,x);
            }
            dfs(1,1);
            cout<<f[1][k][1]<<endl;
        }    
    }
    View Code

    嘛,比较难想的dp(其实不是难想啦....就是复杂一点而已)

    嘛直接先套树形背包模板  但发现不足以表达所有状态....

    于是乎再加一维!!!!(是否一定在根节点)

    然后转移就好了

    1.一定在根节点

            1.其他子节点先到根,然后再转移当前子树

    2.不一定在根节点

            1.先往其他子树绕一圈回来,然后回来后再直接往下面走

            2.从当前子树绕一圈回来,然后再接着走

    然后这题就结束了

  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/shatianming/p/12299469.html
Copyright © 2011-2022 走看看