高质量好题:NOI2006 网络收费

质量很高,题目很好,思路巧妙。

奈何这里空白太小,我写不下。

于是记录一下学到的一个最有用的思路:当dp转移存在某些优先级顺序依赖的时候,可以用 dfs 记录其中一个维度的状态,不仅好写,还能省很多空间。

例如这一题,如果不用dfs的话,就要用一个非常屎的把两维信息丢到一维储存的压缩方式,需要的时候再提取。

不失为一种好方法,但是很难调我写了,没调出来

void dfs(int u,int now,int l=1,int r=(1<<n)){
    if(l==r){
        g[u][0]=c[u-(1<<n)+1][0],g[u][1]=c[u-(1<<n)+1][1];
        for(ri x=now,v=u>>1;v;x>>=1,v>>=1){
            if(x&1) g[u][1]+=f[u][v];
            else g[u][0]+=f[u][v];
        }
        return ;
    }
    int len=(r-l+1);
    int mid=l+r>>1;
    dfs(lc,now<<1|1,l,mid),dfs(rc,now<<1|1,mid+1,r);
    for(ri i=0;i<=len/2;++i){
        g[u][i]=1e18;
        for(ri j=0;j<=len/2&&j<=i;++j)
            g[u][i]=min(g[u][i],g[lc][j]+g[rc][i-j]);
    }
    dfs(lc,now<<1,l,mid),dfs(rc,now<<1,mid+1,r);
    for(ri i=len/2+1;i<=len;++i){
        g[u][i]=1e18;
        for(ri j=i-len/2;j<=len/2&&j<=i;++j)
            g[u][i]=min(g[u][i],g[lc][j]+g[rc][i-j]);
    }
}

用了 dfs 之后就非常清新而且好写了。

posted @ 2021-07-21 19:38  krimson  阅读(27)  评论(0编辑  收藏  举报