zoukankan      html  css  js  c++  java
  • POJ 1155

        dp[x][y]代表以x为根的子树..连接了y个终端用户(叶子)..所能获得的最大收益...

        dp[x][ ]可以看成当根为x时..有个背包空间为0~m...每个空间上记录了到到达这个空间的最大收益..

        典型的泛化背包问题... 


    Program:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<set>
    #include<ctime>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<map>
    #define oo 100000007
    #define ll long long
    #define pi acos(-1.0)
    #define MAXN 3005
    using namespace std;
    struct node
    {
          int x,y,c,next;
    }line[MAXN];
    int n,m,_next[MAXN],v[MAXN],dp[MAXN][MAXN],SubNum[MAXN];
    void addline(int x,int y,int c,int m)
    {
          line[m].next=_next[x],_next[x]=m;
          line[m].x=x,line[m].y=y,line[m].c=c;
          return;
    }
    void dfs(int x)
    {
          int k=_next[x]; 
          SubNum[x]=dp[x][0]=0;
          if (!k) dp[x][1]=v[x],SubNum[x]=1;
          else
          while (k)
          {
                int i,j,y=line[k].y;
                dfs(y);
                SubNum[x]+=SubNum[line[k].y];
                for (i=SubNum[x];i>=1;i--)
                   for (j=0;j<=SubNum[y] && j<=i;j++)
                      dp[x][i]=max(dp[x][i],dp[x][i-j]+dp[y][j]+line[k].c); //泛化背包转移
                k=line[k].next;
          }
          return;
    }
    int main()
    {
          int i,num,t; 
          while (~scanf("%d%d",&n,&m))
          {
                 num=0;
                 memset(_next,0,sizeof(_next));
                 memset(dp,-0x1f,sizeof(dp));
                 memset(v,0,sizeof(v));
                 memset(SubNum,0,sizeof(SubNum));
                 for (i=1;i<=n-m;i++)
                 {
                       scanf("%d",&t);
                       while (t--)
                       {
                             int A,C;
                             scanf("%d%d",&A,&C);
                             addline(i,A,-C,++num);
                       } 
                 }
                 for (i=n-m+1;i<=n;i++) scanf("%d",&v[i]);
                 dfs(1);
                 for (i=m;i>=1;i--)
                   if (dp[1][i]>=0) break;
                 printf("%d
    ",i);
          }
          return 0;
    }
    


  • 相关阅读:
    java基础入门-arraylist存储开销
    java基础入门-iterator迭代器与集合下标的使用
    java基础入门-泛型(1)-为什么需要使用泛型?
    vue路由懒加载
    js防抖和节流
    vue 生命周期函数详解
    createElement 函数
    vue中Runtime-Compiler和Runtime-only的区别
    箭头函数以及this指向问题
    webpackES6语法转ES5语法
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3202869.html
Copyright © 2011-2022 走看看