• poj1155 TELE (树上分组背包)


    题目链接:https://vjudge.net/problem/POJ-1155

    题意:给定一颗以1为根的边权树,有n个结点,其中m个叶子结点,每个叶子结点有一个价值。要求从m个叶子结点中选最多的结点,费用是从根节点到叶子结点的边权和,价值是所有选中的叶子结点价值和。

    思路:

      树上分组背包。用dp[u][j]表示对于结点u的子树,选j个叶子结点的最大利润,即价值-花费。因为对u的每个子结点v1,v2,v3,在v1的子树中最多选择一种方案,不可能重叠选择,所以是分组背包。先处理出num[u],表示结点u的子树中叶子结点的个数。

      那么对于叶子结点u:dp[u][j]=a[u](a[u]是叶子结点u的价值)

        对于非叶子结点u:dp[u][j]=max(dp[u][j] , dp[u][j-k]+dp[v][k]-len),其中j是最大容量,k是枚举的容量。

      dp数组初始化为负无穷,因为一条利润为负数的方案在后面也可以和另一条利润正的方案合并,最终利润仍为正。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn=3005;
    const int ninf=0xcfcfcfcf;
    int n,m,head[maxn],a[maxn],cnt,dp[maxn][maxn],num[maxn];
    
    struct node{
        int v,w,nex;
    }edge[maxn];
    
    void adde(int u,int v,int w){
        edge[++cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].nex=head[u];
        head[u]=cnt;
    }
    
    void dfs(int u){
        if(!head[u]){
            dp[u][1]=a[u];
            num[u]=1;
            return;
        }
        for(int i=head[u];i;i=edge[i].nex){
            int v=edge[i].v;
            dfs(v);
            num[u]+=num[v];
        }
        for(int i=head[u];i;i=edge[i].nex){
            int v=edge[i].v;
            for(int j=num[u];j>=1;--j)
                for(int k=1;k<=min(j,num[v]);++k)
                    if(dp[u][j-k]!=ninf&&dp[v][k]!=ninf)
                        dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-edge[i].w);
        }
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                dp[i][j]=ninf;
        for(int i=1;i<=n-m;++i){
            int k,t1,t2;
            scanf("%d",&k);
            for(int j=1;j<=k;++j){
                scanf("%d%d",&t1,&t2);
                adde(i,t1,t2);
            }
        }
        for(int i=n-m+1;i<=n;++i)
            scanf("%d",&a[i]);
        dfs(1);
        for(int i=m;i>=0;--i)
            if(dp[1][i]>=0){
                printf("%d
    ",i);
                break;
            }
        return 0;
    }
  • 相关阅读:
    -bash: belts.awk: command not found
    PLS-00357: Table,View Or Sequence reference 'SEQ_TRADE_RECODE.NEXTVAL' not allowed in this context
    初识makefile
    proc:基本数据库操作
    ORA-12154: TNS:could not resolve the connect identifier specified
    简单的爬虫
    合并一个文文件夹下的所有Excel文件
    Python 递归读取文件夹内所有文件名(包含子文件夹)
    CSS
    JQ
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11434942.html
Copyright © 2020-2023  润新知