• bzoj4813 [Cqoi2017]小Q的棋盘


    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,Bi<V 

    Output

    输出一行一个整数,表示最多经过的格点数量。

    Sample Input

    5 2
    1 0
    2 1
    3 2
    4 3

    Sample Output

    3
    从格点 0 出发移动 2 步。经过 0, 1, 2 这 3 个格点。

    正解:树形$dp$。

    比较简单的树形$dp$。设$f[x][i]$为$x$出发,走$i$步,没有回到$x$的最多点数;$g[x][i]$为$x$出发,走$i$步,回到$x$的最多点数。

    然后有$3$个转移,分别是$x$从自己没走回来的状态和儿子走回来的状态转移;从自己走回来的状态和儿子没走回来的状态转移;还有一个就是$g$的转移。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define N (510)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 struct edge{ int nt,to; }g[N];
    23 
    24 int f[N][N],t[N][N],h[N],l[N],head[N],n,k,num;
    25 
    26 il int gi(){
    27     RG int x=0,q=1; RG char ch=getchar();
    28     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    29     if (ch=='-') q=-1,ch=getchar();
    30     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    31     return q*x;
    32 }
    33 
    34 il void insert(RG int from,RG int to){
    35     g[++num]=(edge){head[from],to},head[from]=num; return;
    36 }
    37 
    38 il void dfs(RG int x,RG int p){
    39     f[x][0]=t[x][0]=1; RG int v;
    40     for (RG int i=head[x];i;i=g[i].nt){
    41     v=g[i].to; if (v==p) continue; dfs(v,x);
    42     for (RG int j=0;j<=k;++j) h[j]=t[x][j],l[j]=f[x][j];
    43     for (RG int p=0;p<=k;++p)
    44         for (RG int q=0;q<=k;++q){
    45         f[x][p+q+1]=max(f[x][p+q+1],h[p]+f[v][q]);
    46         f[x][p+q+2]=max(f[x][p+q+2],l[p]+t[v][q]);
    47         t[x][p+q+2]=max(t[x][p+q+2],h[p]+t[v][q]);
    48         }
    49     }
    50     for (RG int i=1;i<=k;++i) f[x][i]=max(f[x][i],f[x][i-1]),t[x][i]=max(t[x][i],t[x][i-1]); return;
    51 }
    52 
    53 il void work(){
    54     n=gi(),k=gi();
    55     for (RG int i=1,u,v;i<n;++i)
    56     u=gi(),v=gi(),insert(u,v),insert(v,u);
    57     dfs(0,0); printf("%d
    ",f[0][k]); return;
    58 }
    59 
    60 int main(){
    61     File("chess");
    62     work();
    63     return 0;
    64 }
  • 相关阅读:
    分页bootstrap
    导航条bootstrap
    导航bootstrap
    栅格系统bootstrap
    「ICPC2015 WF」Pipe Stream
    「LOJ#3399」Communication Network
    「WC2019」数树
    「UTR #3」量子破碎
    XJOI1105模拟赛 积木游戏
    XJOI1104NOIP模拟赛
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6974052.html
Copyright © 2020-2023  润新知