POJ1155-树形DP&&背包

来源:互联网 发布:linux 端口转发到外部 编辑:程序博客网 时间:2024/06/06 03:54

技巧:num数组,用来记录在此树上最多选择多少个。其他就是背包了

#include <cstdlib>#include <cstdio>#include <iostream>#include <cstring>using namespace std;const int maxn=3002;int m,n;int len;int dp[maxn][maxn],tem[maxn],a[maxn][maxn],head[maxn],num[maxn];struct node{  int now;   int val;   int next;}tree[9005];void add(int a,int b,int c){  tree[len].now=a;   tree[len].val=b;   tree[len].next=head[c];//建立一个树,链式前进星,    head[c]=len++;}int dfs(int root){   int p;    for(int i=head[root];i!=-1;i=tree[i].next)       {   p=tree[i].now;             dfs(p);           for(int l=0;l<=num[root];l++)                tem[l]=dp[root][l];            for(int k=0;k<=num[root];k++)              for(int j=1;j<=num[p];j++)           {     dp[root][k+j]=max(dp[root][j+k],dp[p][j]+tem[k]-tree[i].val);           }           num[root]+=num[p];       }    return 0;}int main(){int a,b;int k;   while(~scanf("%d%d",&n,&m))   {   len=0;   memset(head,-1,sizeof(head));       for(int i=1;i<=n-m;i++)        {   scanf("%d",&k);            num[i]=0;           for(int c=0;c<k;c++)             {scanf("%d%d",&a,&b);              add(a,b,i);}        }        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)            dp[i][j]=-9999999;        for(int i=n-m+1;i<=n;i++)        {scanf("%d",&dp[i][1]);        num[i]=1;}         dfs(1);         //for(int i=1;i<=n-m;i++)            // printf("%d  ",head[i]);         //printf("^^^^\n");         for(int i=m;i>=0;i--)         {    //printf("%d  ",dp[i][1]);             if(dp[1][i]>=0)               {printf("%d\n",i);break;}         }   }    return 0;}
原创粉丝点击