poj 1155 TELE (树形dp)

来源:互联网 发布:中国电子商务发展数据 编辑:程序博客网 时间:2024/05/23 20:35

设dp[u][j]为以u为根的子树,分配了j个用户的所能获得的最大收益。
最后找出令dp[1][j]>=0的最大的j即可。

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define N 3005using namespace std;vector<int>edge[N];int c[N],dp[N][N];int dfs(int u){        int i,len=edge[u].size(),v,j,k,sum=0;        dp[u][0]=0;        if(!len) dp[u][1]=0,sum=1;        for(i=0;i<len;i++){                v=edge[u][i];                sum+=dfs(v);                for(j=sum;j>0;j--){                        for(k=1;k<=j;k++){                                dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]+c[v]);                        }                }        }        return sum;}int main(){        int n,m,i,k,j;        scanf("%d%d",&n,&m);        memset(dp,-50,sizeof(dp));        for(i=1;i<=n-m;i++){                scanf("%d",&k);                for(j=1;j<=k;j++){                        int a;                        scanf("%d",&a);                        scanf("%d",c+a);                        c[a]=-c[a];                        edge[i].push_back(a);                }        }        for(j=1;j<=m;j++) scanf("%d",&k),c[n-m+j]+=k;        dfs(1);        bool flag=0;        for(j=m;j>=0;j--){                if(dp[1][j]>=0){                        flag=1;                        printf("%d\n",j);                        break;                }        }        if(!flag) printf("0\n");        return 0;}
0 0
原创粉丝点击