POJ2486 apple tree(樹形DP)

題目大意:

給出一個有n個節點的樹,每個節點上有個權值,問不超過k步最多能遍歷到的權值。
輸入: 輸入n和k,然後是n個節點的值,然後是n-1個i j代表了i和j節點相鄰。
輸出:最多能遍歷到的權值。

思路:樹形dp:d[0][x][j+2] = max(d[0][x][j+2],d[0][v][k]+d[0][x][j-k]);
d[1][x][j+2] = max(d[1][x][j+2],d[0][v][k]+d[1][x][j-k]);
d[1][x][j+1] = max(d[1][x][j+1],d[1][v][k]+d[0][x][j-k]);

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int d[2][105][205],a[105],t[105],b[105][105],n,m;//數組定大了會TLE
bool c[105];
void ans(int x){//dfs
    int i,j,k,v;
    for(i=0;i<=m;i++)
        d[0][x][i]=d[1][x][i]=a[x];
    c[x]=1;
    for(i=1;i<=t[x];i++){
        v=b[x][i];
        if(0==c[v]){
            ans(v);
            for(j=m;j>=0;j--)//樹形dp
                for(k=0;k<=j;k++){
                      d[0][x][j+2] = max(d[0][x][j+2],d[0][v][k]+d[0][x][j-k]);  
                      d[1][x][j+2] = max(d[1][x][j+2],d[0][v][k]+d[1][x][j-k]);  
                      d[1][x][j+1] = max(d[1][x][j+1],d[1][v][k]+d[0][x][j-k]); 
                }
        }
    }
}
int main(){
    int i,j,k,x,y;
    while(scanf("%d%d",&n,&m)!=EOF){ 
        memset(d,0,sizeof(d));  //清空
        memset(b,0,sizeof(b));  
        memset(t,0,sizeof(t));  
        memset(c,0,sizeof(c));  
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);//讀入
            b[x][++t[x]]=y;
            b[y][++t[y]]=x;
        }
        ans(1);
        printf("%d\n",d[1][1][m]);//輸出1-n的最大值
    }
    return 0;
}

本程序爲博主親自寫且ac的,請勿抄襲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章