首页 > 其他 > 详细

【洛谷P1273】有线电视网

时间:2018-08-03 19:20:30      阅读:140      评论:0      收藏:0      [点我收藏+]

有线电视网

题目链接

树形DP,分组背包

dp[u][i][j]表示以u为根的子树,前i个子树中选j个用户的最大收益.

dp[u][size[u]][0]=0;

dp[u][i][j]=max(dp[u][i][j],dp[u][i-1][j-k]+dp[v][size[v]][k]-w[u][v]);

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 3010
int n,m,dp[N][N],val[N];
struct NODE{
    int to,w,next;
} e[N];
int Head[N],num;
inline void add(int x,int y,int w){
    e[++num].to=y;
    e[num].w=w;
    e[num].next=Head[x];
    Head[x]=num;
}
inline int read(){
    int x=0; char c=getchar();
    while(c<0||c>9) c=getchar();
    while(0<=c&&c<=9) { x=(x<<3)+(x<<1)+c-0; c=getchar(); }
    return x;
}
int dfs(int u){
    dp[u][0]=0;
    if(u>n-m){
        dp[u][1]=val[u];
        return 1;
    }
    int sum=0;
    for(int i=Head[u];i;i=e[i].next){
        int v=e[i].to;
        int sz=dfs(v);
        for(int j=sum;j>=0;j--)
         for(int k=1;k<=sz;k++)
          dp[u][j+k]=max(dp[u][j+k],dp[u][j]+dp[v][k]-e[i].w);
        sum+=sz;
    }
    return sum+1;
}
int main()
{
    memset(dp,~0x3f,sizeof(dp));
    n=read(); m=read();
    int snum,y,w;
    for(int i=1;i<=n-m;i++){
        snum=read();
        while(snum--){
            y=read(); w=read();
            add(i,y,w);
        }
    }
    for(int i=n-m+1;i<=n;i++)
     val[i]=read();
    dfs(1);
    int ans=0;
    for(ans=m;ans>=1;ans--)
     if(dp[1][ans]>=0) break;
    printf("%d\n",ans);
    return 0;
}

 

【洛谷P1273】有线电视网

原文:https://www.cnblogs.com/yjkhhh/p/9415794.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!