題意:由n個結點組成的樹,每個結點有個點權,你從結點1出發,問最多走m步可以獲得點權和(重複走乙個結點只有第一次走過會
獲得點權值)的最大值。
思路:設dp[i][j][k]表示從i結點走j步( k=0表示回到i結點共j步,k=1表示j步之後不回到i節點 )可獲得點權和的最大值。
考慮當前的結點u,以及它的子結點v,那麼只有三種情況。
(1)dp[u][j + 2][0]=max( dp[u][j + 2][0],dp[u][j - k][0]+ dp[v][k][0] ),即從u向下走了並回到
u共j - k步,接下來又走到v,從v向下走並回到v共k步,再回到u的情況。
(2)dp[u][j + 1][1]=max( dp[u][j + 1][1],dp[u][j - k][0]+ dp[v][k][1] ),即從u向下走並回到u共
j - k步,接下來走到v,並從v向下走k步不回到v的情況。
(3)dp[u][j + 2][1]=max( dp[u][j + 2][1],dp[u][j - k][1]+ dp[v][k][0] ),即從u走到v,並從v向下走
並回到v共k步,再回到u。之後u再向下走j - k步不回到u的情況。
詳見**:
// file name: poj2486.cpp //
// author: kereo //
// create time: 2023年11月03日 星期一 14時38分35秒 //
//***********************************//
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
const int sigma_size=26;
const int maxn=200+100;
const double eps=1e-8;
const int inf=0x3fffffff;
const int mod=1000000000+7;
#define l(x) (x<<1)
#define r(x) (x<<1|1)
int n,m,edge_cnt;
int dp[maxn][maxn][2],num[maxn],head[maxn];
struct edge
edge[maxn<<1];
void init()
void addedge(int u,int v)
void dfs(int u,int fa) }}
int main()
{ while(~scanf("%d%d",&n,&m)){
init();
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
int u,v;
for(int i=1;i
poj 2486 (樹形dp (好題))
最近做了些樹形dp的題目,感覺對這種將每棵子樹都當做乙個物品處理的樹形揹包題目理解還不夠深刻,果然這題就被破的很慘,但好在想了很長時間想清楚了,這題就是求從一顆帶點權樹的根節點出發,走過k條邊能獲得的最大權值。考慮某乙個節點u,肯定有一維狀態表示從該節點開始還可以走多少條邊,但最優決策有可能是從u的...
樹上揹包 POJ2486 Apple Tree
一棵樹n 100 個節點,每個節點有a i 個蘋果,從1出發走k 200 步,問最多能得到多少個蘋果。首先想到每個節點只有3種情況,要麼不經過,要麼經過了最後回來,要麼經過了最後不回來,只用關心後兩種就行。於是可以想到乙個dp i j k 表示從i出發走j步,k 0表示回來,k 1表示不回來,現在想...
POJ2486 Apple Tree 樹上揹包
一句話題意 一棵樹,一共n個點,每個點上有乙個權值,求從1出發,走k步,最多能遍歷到的權值。可以往回走。第一 二 道樹上揹包題,先是看了dalao的題解,改了一點就過樣例了。然而.tle?改了挺久發現由於多組資料且沒有 0 0 的輸入,如果不在讀入的時候加 或 eof 就會死迴圈,從而導致tle。狀...