[CQOI2017]小Q的棋盘

题目大意:
  给你一个$n(nle100)$个点的树和一个数$m$,问从给定的点出发,任意游走$m(mle100)$次最多能走过几个点(重复经过点不计入答案)?

思路:
  一眼看上去有种贪心的感觉。看Status里面一堆0ms的,AC率又那么高,果断写了一个$O(n)$贪心,每次贪心地走完最深的子树,结果交上去才30分,发现有时子树走一半就上去反而更优。
  考虑一个$O(n^3)$的DP。用$f[i][j]$表示$i$结点为根的子树走$j$次最后回到$i$最多能经过的点数,$g[i][j]$表示$i$结点为根的子树走$j$次步数用尽不回到$i$最多能经过的点数。转移方程显然:
  $f[x][i]=max{f[x][i-j-2]+f[y][j]}$
  $g[x][i]=max(max{f[x][i-j-1]+g[y][j]},max{g[x][i-j-2]+f[y][j]})$
  交一发80ms,看题解后发现那些0ms的人其实用的也是贪心,枚举结束位置的点,让剩下的步数尽量用完,即答案为$frac{min(max{dep[i]},m)+m}2+1$。时间复杂度$O(n)$。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<cstring>
 4 #include<algorithm>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=100,M=200;
13 int m,h[N],sz,f[N][N+1],g[N][N+1];
14 struct Edge {
15     int to,next;
16 };
17 Edge e[M];
18 inline void add_edge(const int &u,const int &v) {
19     e[sz]=(Edge){v,h[u]};h[u]=sz++;
20     e[sz]=(Edge){u,h[v]};h[v]=sz++;
21 }
22 inline void dfs(const int &x,const int &par) {
23     f[x][0]=g[x][0]=1;
24     for(int i=h[x];~i;i=e[i].next) {
25         const int &y=e[i].to;
26         if(y==par) continue;
27         dfs(y,x);
28         for(register int i=m;i;i--) {
29             for(register int j=0;j<i;j++) {
30                 if(i-j-2>=0) {
31                     f[x][i]=std::max(f[x][i],f[x][i-j-2]+f[y][j]);
32                     g[x][i]=std::max(g[x][i],g[x][i-j-2]+f[y][j]);
33                 }
34                 g[x][i]=std::max(g[x][i],f[x][i-j-1]+g[y][j]);
35             }
36         }
37     }
38     for(register int i=1;i<=m;i++) {
39         f[x][i]=std::max(f[x][i],f[x][i-1]);
40         g[x][i]=std::max(g[x][i],g[x][i-1]);
41     }
42 }
43 int main() {
44     memset(h,-1,sizeof h);
45     const int n=getint();m=getint();
46     for(register int i=1;i<n;i++) {
47         add_edge(getint(),getint());
48     }
49     dfs(0,0);
50     printf("%d
",g[0][m]);
51     return 0;
52 }
原文地址:https://www.cnblogs.com/skylee03/p/8782704.html