description
小q正在設計一種棋類遊戲。在小q設計的遊戲中,棋子可以放在棋盤上的格點中。某些格點之間有連線,棋子只能
在有連線的格點之間移動。整個棋盤上共有v個格點,編號為0,1,2…,v-1,它們是連通的,也就是說棋子從任意格
點出發,總能到達所有的格點。小q在設計棋盤時,還保證棋子從乙個格點移動到另外任一格點的路徑是唯一的。
小q現在想知道,當棋子從格點0出發,移動n步最多能經過多少格點。格點可以重複經過多次,但不重複計數。
input
第一行包含2個正整數v,n,其中v表示格點總數,n表示移動步數。
接下來v-1行,每行兩個數ai,bi,表示編號為ai,bi的兩個格點之間有連線。
v,n≤ 100, 0 ≤ai,bioutput
輸出一行乙個整數,表示最多經過的格點數量。
sample input
5 2
1 02 1
3 24 3
sample output
3
題解
我覺得我好辣雞。。想到是樹形dp結果不會轉移。。最後發現轉移賊簡單
設g[x][i]表示從x走i步不回來
f[x][i]表示從x走i步最後回到x點
轉移如下
g[x][i]=max(g[x][i],g[y][j-1]+f[x][i-j]);
不回來的話,就要留一步從子樹回來的,還有從其他子樹過來的
f[x][i]=max(f[x][i],f[y][j-2]+f[x][i-j]);
回來,那麼我走下去還要走回來,這棵子樹和其他子樹一起回到我
g[x][i]=max(g[x][i],f[y][j-2]+g[x][i-j]);
不回來 上面算了在現在的子樹不回來 那麼現在算其他子樹不回來
#include
#include
#include
#include
#include
using
namespace
std;
struct node
a[210];int len,last[110];
void ins(int x,int y)
int g[110][110],f[110][110];
//g[x][i]從x往下走i步,不回來
//f[x][i]從x往下走i步,回來
int n,m;
void treedp(int x,int fa)}}
}}int main()
treedp(1,0);
printf("%d\n",g[1][m]);
return
0;}
BZOJ4813 Cqoi2017 小Q的棋盤
找以起點為起點的乙個最長鏈,最優一定是在最長鏈上不走回頭路的,所以相當於最長鏈上的邊代價是1,非最長鏈的邊代價是2 因為要走回去 每付出一次代價就可以使訪問到的點數 1,那麼貪心即可 include include include include include include include in...
bzoj4813 Cqoi2017 小Q的棋盤
小q正在設計一種棋類遊戲。在小q設計的遊戲中,棋子可以放在棋盤上的格點中。某些格點之間有連線,棋子只能在有連線的格點之間移動。整個棋盤上共有v個格點,編號為0,1,2 v 1,它們是連通的,也就是說棋子從任意格點出發,總能到達所有的格點。小q在設計棋盤時,還保證棋子從乙個格點移動到另外任一格點的路徑...
BZOJ4813 Cqoi2017 小Q的棋盤
給出一棵樹,從根節點出發,走n步,求最多能經過多少個點 重複經過不算 貪心本來想著樹形dp,太麻煩了,懶得碼 首先我們把最長鏈留到最後走,這樣子我們就可以一次性將最長鏈走完了,那麼最長鏈的每條邊的代價就是1 而其它邊的代價就為2 因為要往回走 然後貪心就好了 特殊情況 1.最長鏈的長度 步數,直接輸...