我定义的 dp 是:
f[i][j] 表示 i 子树经过 j 步不一定走回 i 经过的最大格子数,g[i][j] 表示 j 子树经过 j 步走回 i 的最大格子数。
所以这样 dp 完的答案应该是 f[1][N].
然而写完后发现,输出 f[1][N] 的答案是偏小的。
而对 [1,N] 的所有步数取 max 即 Ans=maxi∈[1,N]{dp[1][i]}
的答案是对的但这似乎和定义不符。
想求问下原因。或者是 dp 转移错了?)
#include<bits/stdc++.h>
using namespace std;
const int MAXN=200;
const int dyx=(1<<30);
int N,V,siz[MAXN];
int tot,head[MAXN];
int f[MAXN][MAXN],g[MAXN][MAXN];
int F[MAXN][MAXN],G[MAXN][MAXN];
struct E{int nxt,to;}e[MAXN];
inline int Max(int x,int y){return x>y?x:y;}
inline int Min(int x,int y){return x<y?x:y;}
inline void add(int x,int y){
e[++tot]=(E){head[x],y};
head[x]=tot;
}
void dfs(int x,int fa){
f[x][0]=g[x][0]=1;
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].to;
if(j==fa)continue;
dfs(j,x);
for(int T=0;T<=N;++T)G[x][T]=g[x][T],F[x][T]=f[x][T];
for(int T=N;T>=0;--T){
for(int k=0;k<=T;++k){
if(T-k-1>=0)f[x][T]=Max(f[x][T],G[x][T-k-1]+f[j][k]);
if(T-k-2>=0)g[x][T]=Max(g[x][T],G[x][T-k-2]+g[j][k]),f[x][T]=Max(f[x][T],F[x][T-k-2]+g[j][k]);
}
}
}
}
int main(){
freopen("111.txt","r",stdin);
// freopen("my.out","w",stdout);
scanf("%d%d",&V,&N);
for(int i=1;i<V;++i){
int x,y;
scanf("%d%d",&x,&y);
x++;y++;
add(x,y);add(y,x);
}
// memset(f,-0x3f,sizeof f);
// memset(g,-0x3f,sizeof g);
dfs(1,0);
int ans=-dyx;
for(int i=0;i<=N;++i)ans=Max(ans,Max(f[1][i],0));
cout<<ans<<endl;
return 0;
}