这是我在做 CF815C Karen and Supermarket 时发现的问题,关于树形背包转移时的问题。
下面这个是我最开始的代码,也是我一贯的树形背包写法(只截取了关键的一部分):
siz[u] += siz[v];
for(int j=siz[u];j>=0;j--)
for(int k=0;k<=min(siz[v], j);k++)
{
f[u][j][1] = min(f[u][j][1], f[u][j-k][1]+min(f[v][k][0], f[v][k][1]));
f[u][j][0] = min(f[u][j][0], f[u][j-k][0]+f[v][k][0]);
}
这份代码在 Codeforces 上收获了 Time limit exceeded on test 17
的好成绩。
于是我参考了题解,发现题解中的这部分代码形式如下:
for(int j=siz[u];j>=0;j--)
for(int k=0;k<=siz[v];k++)
{
f[u][j+k][1] = min(f[u][j+k][1], f[u][j][1]+min(f[v][k][0], f[v][k][1]));
f[u][j+k][0] = min(f[u][j+k][0], f[u][j][0]+f[v][k][0]);
}
siz[u] += siz[v];
将上面的部分改成这样即可 AC。
两份代码不同的地方似乎只有更新 siz[u]
的时间点,以及相应转移时循环变量 j
的含义。
所以我的问题是:
为什么第一份代码会 TLE?
如何构造卡第一份代码的数据?