HDU1520 Anniversary party 树形DP

HDU1520 Anniversary party


题面:

给一颗树,每个结点都有各自的价值,选择一些不相邻的结点使得收益最大。


解题过程:

  • 树上相邻的结点不能同时选上,用 f [ x ][ 2 ] 第二维的 0 和 1 来表示不选和选这个节点所能达到的最大收益。
  • 状态转移方程为:
    f[x][0] += max( (ll)0, max(f[y][0], f[y][1]));
    f[x][1] += max( f[y][0], (ll)0);

  • 关于数据。之前交了POJ2342,用的是错误的转移方程(先把子节点全选的收益res_0 和 全不选的收益 res_0 计算出来,再进行转移),居然AC了。说明这个题POJ的数据比HDU要水很多。


AC代码:

#include<iostream>
#include<cstring>
using namespace std;
#define rep(i,l,p) for(int i=l;i<=p;i++)
#define fread() freopen("in.txt","r",stdin)
typedef long long ll;
typedef pair<int,int> P;
#define Fi first
#define Se second
#define mp make_pair
int n;
int v[6005];
int head[6005],tot;
struct Edge
{
    int v,nx;
}edge[6600];
void add(int u,int v){
    edge[++tot].nx = head[u]; head[u] = tot;
    edge[tot].v = v;
}
int dig[66000];
ll f[6600][2];
void solve(int x){
    f[x][1] = v[x];
    if(head[x] == -1) return;
    ll res_0 = 0,res_1 = 0;
    for(int i=head[x];i!=-1;i=edge[i].nx){
        int y = edge[i].v;
        solve(y);
        f[x][0] += max((ll)0,max(f[y][0],f[y][1]));
        f[x][1] += max(f[y][0],(ll)0);

    }
//  f[x][0] = max(f[x][0],res_1);

}
int main(int argc, char const *argv[])
{
    //fread();
    ios::sync_with_stdio(false);
    while(cin >> n){
        memset(head,-1,sizeof head); tot =0;
        rep(i,1,n) cin >> v[i];
        memset(dig,0,sizeof dig);
        memset(f,0,sizeof f);

        int u,to;
        while(cin >> to >> u && u && to){
            add(u,to);
            dig[to]++;
        }
        int root;
        rep(i,1,n){
            if(dig[i] == 0) {
                root = i;
                break;
            }
        }
        solve(root);
        ll ans = max(f[root][0],f[root][1]);
    //  rep(i,1,n) cout << f[i][0] << " " << f[i][1] << endl;
        cout << ans << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值