高質量好題:NOI2006 網路收費
阿新 • • 發佈:2021-07-21
。。。
質量很高,題目很好,思路巧妙。
奈何這裡空白太小,我寫不下。
於是記錄一下學到的一個最有用的思路:當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 之後就非常清新而且好寫了。