1. 程式人生 > 其它 >高質量好題:NOI2006 網路收費

高質量好題: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 之後就非常清新而且好寫了。