POJ2486 apple tree(树形DP)

39 篇文章 0 订阅
32 篇文章 0 订阅

题目大意:

给出一个有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的,请勿抄袭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值