程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1155 - TELE 樹型DP(泛化背包轉移)..

POJ 1155 - TELE 樹型DP(泛化背包轉移)..

編輯:C++入門知識

 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\n",i);
      }
      return 0;
}

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved