• poj 1155 树形背包


    http://blog.csdn.net/libin56842/article/details/9908199

    树形背包:

    首先是建树,每个结构体为一个节点,包括下一个点序号,值,和next。

    tree[ptr]会保存所有的节点序列,而head数组则是保存每个节点的最后一个子节点序列中的位置,next则是保存上一个子节点在序列中的位置,若没有则为-1。

    遍历时从i=head[root]出发,到i=-1结束,不断往子节点遍历,同一层之间用next遍历,就可以遍历树的所有节点。

    树状dp。由于求的是最多多少用户,那么我们可以把用户个数当成一个状态。dp[i][j]代表i节点为根节点的子树j个用户的时候最大剩余费用。

         则dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]-w[i][son]);

    注意两点,第一点是上面式子中的dp[i][k]必须先用一个tem[MAX]数组提取出来,因为在计算的过程中会相互影响。第二点是价值可能是负值,所以dp初始化的时候要初始化为负的最大值。

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <vector>
    #include <iterator>
    #include <set>
    #include <map>
    #include <sstream>
    using namespace std;
    
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pf printf
    #define sf scanf
    #define spf sprintf
    #define pb push_back
    #define debug printf("!
    ")
    #define MAXN 1010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #define LL long long
    #define ALL(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    #define pqueue priority_queue
    #define INF 0x3f3f3f3f
    
    int n,m;
    
    struct node
    {
        int y,val,next;
    }tree[9005];
    
    int head[3005],dp[3005][3005],num[3005],tem[3005],ptr=1;
    
    
    void add(int x,int y,int val)
    {
        tree[ptr].y = y;
        tree[ptr].val = val;
        tree[ptr].next = head[x];
        head[x] = ptr++;
    }
    
    void dfs(int root)
    {
        int i,j,k;
        for(i=head[root]; i!=-1; i=tree[i].next)
        {
            int p = tree[i].y;
            dfs(p);
    
            for(j=0;j<=num[root];j++)
                tem[j] = dp[root][j];
    
            for(j=0;j<=num[root];j++)
            {
                for(k=1;k<=num[p];k++)
                {
                    dp[root][k+j] = max(dp[root][j+k],tem[j]+dp[p][k]-tree[i].val);
                    //pf("%d %d %d %d
    ",root,j,k,dp[root][j+k]);
                }
            }
            num[root]+=num[p];
        }
    }
    
    int main()
    {
        int i,j,k,a,b;
        while(~sf("%d%d",&n,&m) && m+n)
        {
            mem(head,-1);
            for(i=1;i<=n-m;i++)
            {
                sf("%d",&k);
                num[i] = 0;
                for(j=0;j<k;j++)
                {
                    sf("%d%d",&a,&b);
                    add(i,a,b);
                }
            }
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=m;j++)
                    dp[i][j] = -10000000;
            }
    
            for(i=n-m+1;i<=n;i++)
            {
                num[i] = 1;
                sf("%d",&dp[i][1]);
            }
            dfs(1);
            for(i=m;i>=0;i--)
            {
                if(dp[1][i]>=0)
                {
                    pf("%d
    ",i);
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Cordova Android源代码分析系列一(项目总览和CordovaActivity分析)
    codeforces A. Supercentral Point 题解
    Codeforces441A_Valera and Antique Items(水题)
    POJ 2407 Relatives 欧拉函数题解
    用Qt制作的Android独立游戏《吃药了》公布
    Webserver管理系列:12、开启关闭Ping命令
    高性能 Socket 组件 HP-Socket v3.2.1-RC3 公布
    00092_字符输出流Writer
    np.vstack()和np.hstack()
    用 Python 检验数据正态分布的几种方法
  • 原文地址:https://www.cnblogs.com/qlky/p/5650783.html
Copyright © 2020-2023  润新知