做這道題的時候,我一開始狀態設計的太緊了,我設f(i)表示以i為根的子樹自己搞定自己需要的最小代價,然後我列舉控制根的點。。然後發現轉移是o(n^3)的。
看了**之後發現其實改變一下狀態就可以了,其實顯然的一件事就是我們現在是在列舉兩個點之間的關係了,那麼我們不妨設f(i,j)為j控制i,且以i為根的子樹都被完全搞定的最小代價;那麼狀態轉移方程就呼之欲出了。
①這道題告訴我最大的一點就是當我們發現轉移代價原大於狀態代價的時候,我們不妨將加強狀態以試圖削弱轉移!
我寫**的時候還犯了一些sb錯誤:
②樹的邊有n-1條。。而不是n條!
③為了避免乙個點在佇列中重複出現,我們要用bool陣列判重或保留父親什麼的。。我本來記得判來著,後來不知道為啥sb忘判了。
④然後交到poj上的時候。。沒看見多組資料直接交又wa了一次。
#include#include#includeusing namespace std;
int f[1005][1005],g[1005],w[1005],d[1005];
int next[2005],succ[2005],ptr[1005],etot,l[2005];
inline void addedge(int u,int v,int weight)
int dfna[1005],dfnl[1005],dfnr[1005],dfntot,dfnx[1005];
int q[1005],dis[1005];
bool p[1005];
#define inf 100000000
inline void dfs(int node)
f[node][q[h]]=0;
for(i=ptr[node];i;i=next[i])
if(dfnx[succ[i]]>=dfnl[node]&&dfnx[succ[i]]=dfnl[succ[i]]&&dfnx[q[h]]=dfnl[node]&&dfnx[q[h]]'9')c=getchar();
x=0;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
}int main()
dfs(1);
ans=0x7fffffff;
for(i=n;i;--i)ans=min(ans,f[1][i]+w[i]);
printf("%d\n",ans);
}}
POJ 2152 樹形DP 暴力列舉
題目鏈結 題意 給一顆樹可以在樹上的節點上建立消防站費用為w i 如果不建消防站需要在距離該節點距離小於等於d i 的地方有消防站,求使得整顆樹被覆蓋的最小費用。思路 定義ans陣列 ans u 表示以u為根的子樹的答案 定義dp陣列 dp u v 表示節點u被建立在節點v的消防站覆蓋的最小答案 定...
poj 2152 一道很難的樹型DP
題目 poj 2152 fire 我想說的 以前做揹包的題目做多了,腦子形成了一種就是所有動態規劃就是在陣列上進行等一些固定的思想。結果最近在做一些題目的時候,感覺無從下手,想好久都沒結果。非常慶幸自己做了這類題目,讓我從那種狹隘的思想中做出來。以後就要根據實際情況研究狀態了。題意 有n個城市,每兩...
POJ 2152 Fire(依賴型樹形dp)
poj 2152 fire 題意 給乙個n 個節點和n 1條邊的樹,邊權代表距離,要在這些點中選擇一些點建立消防站,使得每個點都會被消防站覆蓋到。每個點有兩個屬性 co st i 表示在這個點建立消防站的代價,li mit i 表示當某個消防站離 i 的距離不超過li mit i 時,這個點就可以認...