POJ 2486 Apple Tree 樹形DP+分組背包

來源:互聯網
上載者:User

標籤:樹   dp   樹形dp   背包問題   

連結:http://poj.org/problem?id=2486

題意:一棵(蘋果)樹,樹上有N個結點(N<=100),起點是結點1。每個結點上有若干個蘋果,我可以進行K步操作(K<=200),每次操作是從當前結點移動到相鄰的結點,並且到了相鄰的結點以後會吃掉上面的所有蘋果並且蘋果不再長出來,相鄰是指兩個結點之間有邊相連。問在K步操作之後最多可以吃掉多少個蘋果。

思路:剛入手的時候覺得是一般的樹形背包問題,dp[i][j]代表的是以i為根的子樹中走j個結點所能吃到的蘋果數,來進行狀態轉移,但這樣轉移的話每次的轉移消耗就是2(一來一回),但是有可能出現的情況是不回到起點直接到某個點就停下不向前走。

這樣上面的狀態轉移就不能滿足要求。所以要擴充為dp[i][j][k]。

k=0,代表的是最後停在了i的子樹中不回到結點i;k=1,代表的是在i的子樹中走了j個結點並且最後回到了結點j。

狀態轉移方程:

dp[u][i+2][1]=max(dp[u][i+2][1],dp[u][i-j][1]+dp[v][j][1]);表示回到根結點的情況可以通過回到子結點的情況推得。
dp[u][i+1][0]=max(dp[u][i+1][0],dp[u][i-j][1]+dp[v][j][0]);表示不回到根結點的情況可以通過將原來回到根結點的情況由不回到子結點的情況更新得到。
dp[u][i+2][0]=max(dp[u][i+2][0],dp[u][i-j][0]+dp[v][j][1]);表示不回到根結點的情況可以通過將原來不回到根結點的情況由回到子結點的情況更新得到。

這個分組背包表示一種思想上的分組,因為dp[i][j][0]與dp[i][j][1]代表的兩種情況是矛盾的,一定是不能同時出現。最後更新回到根結點時,所有狀態中的最大值即為答案。

代碼:

#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define eps 1e-8#define INF 0x3fffffff#define maxn 105#define maxm 205#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;int head[maxn],top,ans,dp[maxn][maxm][2],N,K,x,y,a[maxn];void init(){    memset(head,-1,sizeof(head));    memset(dp,0,sizeof(dp));    memset(a,0,sizeof(a));    top=0;    ans=0;}struct Edge{    int v;    int next;} edge[maxn*2];void add_edge(int u,int v){    edge[top].v=v;    edge[top].next=head[u];    head[u]=top++;}void dfs(int u,int f){    dp[u][0][0]=dp[u][0][1]=a[u];    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(v==f)            continue;        dfs(v,u);        for(int i=K;i>=0;i--)        {            for(int j=i;j>=0;j--)            {                dp[u][i+2][1]=max(dp[u][i+2][1],dp[u][i-j][1]+dp[v][j][1]);                dp[u][i+1][0]=max(dp[u][i+1][0],dp[u][i-j][1]+dp[v][j][0]);                dp[u][i+2][0]=max(dp[u][i+2][0],dp[u][i-j][0]+dp[v][j][1]);            }        }    }}int main(){    while(~scanf("%d%d",&N,&K))    {        init();        for(int i=1; i<=N; i++)            scanf("%d",&a[i]);        for(int i=1;i<=N-1;i++)        {            scanf("%d%d",&x,&y);            add_edge(x,y);            add_edge(y,x);        }        dfs(1,1);        int ans=0;        for(int i=0;i<=K;i++)        {            if(dp[1][i][0]>ans)                ans=dp[1][i][0];            if(dp[1][i][1]>ans)                ans=dp[1][i][1];        }        printf("%d\n",ans);    }    return 0;}


POJ 2486 Apple Tree 樹形DP+分組背包

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.