程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 1561 依賴背包

hdu 1561 依賴背包

編輯:C++入門知識

題意:n座城堡,每個裡面都有寶物,要求在你可以攻占m個城堡得到的最多的寶物,但是如果要攻破一個城堡,必須要攻破它依賴的那個城堡,例如,如果a依賴b,那麼如果想要攻破a就必須先攻破b。把每個城堡看作是物品,那麼這個物品的城堡數量是1,價值就是寶物了。
解題思路:根據題意知道這種關系會形成一顆多叉樹,根節點是0.從P=0開始,
1、遍歷所有P的孩子,遇到某個孩子還有孩子,就把該節點當作P,繼續1,直到遍歷完所有的節點,如果P的所有孩子都沒有孩子,那麼轉到2,存在有的孩子有孩子,轉到3;
2、對P的所有孩子進行01背包,假設P的價值是Vp,P共有n個孩子,然後對每個孩子進行01背包(因為對於每個城堡只能取一次),那麼可以得到城堡數量從0到n對應的最大價值(0對應的肯定是0了),用dp[i]表示,i代表城堡數量,dp[i]代表價值,接著從i=0開始,都加上P的價值Vp(因為所有的物品都依賴P),同時城堡的個數也加1;最後把得到的n+1個物品保存到P點,這樣,這些物品就相當於分組背包裡面的一組背包了,儲存在castle裡面,然後接著步驟1的遍歷;
3、這個就很簡單了,由於已經遍歷過P所有孩子了,所以,只需要再從頭開始遍歷一遍所有孩子,如果遍歷的孩子還有孩子,那麼就把它的所有孩子當作是分組背包處理,如果遍歷的孩子沒有孩子,那麼就當01背包處理,最後會得到一個城堡數量從0到m(也就是題目給的城堡數量的上限,以為不確定P的所有孩子的個數,所以就用最大的m)對應的最大價值,這個時候,如果P是0,那麼就輸出dp[m]就好了,如果不是,像2一樣,dp[i]代表的價值都加上P的價值,數量也加1,也儲存在castle裡面,繼續步驟1的遍歷;
具體代碼如下:
(提示:結構體s[i]代表城堡i的信息:num表示城堡的數量,value代表價值,key是自身的序號,depend代表i依賴的城堡編號;list castle[i]記錄依賴i的城堡的信息)
[cpp] 
#include <cstdio> 
#include <string.h> 
#include <iostream> 
#include <list> 
 
using namespace std; 
#define N 205 
struct ss{ 
    int num,value,key,depend;//物品的個數,價值,自身的序號,依賴的序號; 
}s[N],one; 
list <ss> castle[N]; 
int dp[N],m; 
void fun(int n) 

    int num=0,i,j,k,minn; 
    list <ss>::iterator p,q; 
    p=castle[n].begin(); 
    while(p!=castle[n].end()) 
    { 
        if(castle[(*p).key].size()!=0) 
            fun((*p).key); 
        p++; 
    }    
    memset(dp,0,sizeof(dp)); 
    p=castle[n].begin(); 
    while(p!=castle[n].end()) 
    { 
        if(castle[(*p).key].size()!=0) 
        {            
            for(i=m;i>=0;i--) 
            { 
                q=castle[(*p).key].begin(); 
                while(q!=castle[(*p).key].end()) 
                { 
                    if(i-(*q).num>=0) 
                    dp[i]=max(dp[i],dp[i-(*q).num]+(*q).value); 
                    q++; 
                } 
            } 
        } 
        else 
        { 
            for(i=m;i>=(*p).num;i--) 
                dp[i]=max(dp[i],dp[i-(*p).num]+(*p).value); 
        } 
        p++; 
    } 
     
    castle[n].clear(); 
    if(!n) 
        cout<<dp[m]<<endl; 
    else 
    { 
        one.depend=n;one.key=n; 
        for(i=m;;i--) 
        { 
            if(dp[i]) 
            { 
                one.num=i+1;one.value=dp[i]+s[n].value; 
                castle[n].push_back(one); 
            } 
            else 
            { 
                one.num=1;one.value=s[n].value; 
                castle[n].push_back(one); 
                break; 
            } 
        } 
    } 
     

 
int main() 

    int n; 
    while(cin>>n>>m) 
    { 
        if(!n&&!m) 
            return 0; 
        int i,j,k,x; 
        for(i=0;i<=n;i++) 
            castle[i].clear(); 
        for(i=0;i<n;i++) 
        { 
            scanf("%d%d",&s[i+1].depend,&s[i+1].value); 
            s[i+1].num=1;   s[i+1].key=i+1; 
            castle[s[i+1].depend].push_back(s[i+1]); 
        } 
        fun(0);  
    } 

作者:jiang199235jiangJJ

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