状态初始化

最近对状态的初始化有点迷...

网上也没有这方面的博客之类的,只能自己悟了...

自己觉得状态初始化应该想状态转移过程中到底有哪个最初状态转移过去的...

例如依赖性背包,就迷了很多天,刚开始的代码:

inline void dfs(int x)
{
    f[x][ww[x]]=vv[x];
    for(int i=0;i<son[x].size();i++)
    {
        int y=son[x][i];
        dfs(y);
        for(int t=m;t>=ww[x];t--)                       
        {
            for(int k=0;k<=t-ww[x];k++) f[x][t]=max(f[x][t],f[x][t-k]+f[y][k]);
        }
    }
}

然后就不出意料的wrong,直到看到正解与我不同,才将f[x][ww[x]]=vv[x];改成for(int i=ww[i];i<=m;i++) f[x][i]=r[i];想不通,那让我们看看状态转移吧!

for(int t=m;t>=ww[x];t--)逆序保证有前面更新后面,符合背包;t>=ww[x]保证在x的节点上必须选x才能进行其子节点的更新;
for(int k=0;k<=t-ww[x];k++)枚举子节点上拿的背包容积,k<=t-ww[x]同样是为了保证t-k之后有大于ww[x]的容积,保证父节点必须拿.
f[x][t]=max(f[x][t],f[x][t-k]+f[y][k])状态转移最关键了,可以发现,f[x][t]都是有之前的[t-k]更新的,之前已经将[t-k]的值限定在ww[x]之上,也就是说由ww[x]之上的值更新,显然只对f[x][ww[x]]赋值是不行的,
所以应该为for(int i=ww[i];i<=m;i++) f[x][i]=r[i],这样就可以让所有状态顺利转移了.

猜你喜欢

转载自www.cnblogs.com/gcfer/p/10607186.html