雅禮 noip2018 模擬賽 day3 T3

2021-08-29 16:20:37 字數 2211 閱讀 6875

典型樹形dp

這裡,我們應該看到一些基本性質:

①:如果這個邊不能改(不是沒有必要改),我們就不改,因為就算改過去還要改回來,顯然不是最優的

注意:「不能改」是指邊的性質和要求的相同而不包括對邊的顏色沒有要求的情況!

②:如果我們每翻轉一條邊,就認為將這條邊的兩個端點度數+1,那麼不難看到,最後翻轉的所有邊構成的路徑總數就是度數為奇數點個數的1/2

(性質②的證明:一條路徑只會對兩端的點產生度數上的影響,而中間的點都是+2,還是偶數,所以無影響)

接下來,我們進行dp:

記狀態f[i][0/1]代表以i為根節點的子樹,0/1代表根節點與父親的邊是否翻轉

那麼我們可以看到,這個dp包含兩部分內容,一部分要保證路徑數最少,另一部分要保證在滿足路徑數最小的前提下路徑總長度最小,所以我們需要同時更新這兩個值,這樣用pair就是乙個比較好的選擇

接下來我們考慮更新:

在更新時我們使用兩個參量:p和q,作為更新dp的中間步驟,用p代表不以i為端點做鏈,q代表以i為端點做鏈,設i的某個子節點為to,於是有:

其中p初始化為(0,0),q初始化為(inf,inf)

解釋一下:這裡pair的add就是對應元素相加(手寫!非內建!)

而min操作表示先按pair第一關鍵字比較,再按第二關鍵字比較

那麼這一步就是乙個合併的過程:

首先,i不作為鏈的端點:分兩類來合併:如果子節點與i的邊翻轉了,那麼就要累在以i為端點的鏈裡(因為i與父親的邊不翻轉,那麼i就將是個端點),如果子節點與i的邊沒有翻轉,那麼僅針對這棵子樹而言,i並沒有作為路徑的端點,所以更新沒有以i為端點鏈的代價

如果i作為鏈的端點,同樣分兩類來合併:如果子節點與i的邊翻轉了,那麼i顯然可以成為鏈的端點,前提是在此之前i並不是鏈的端點,所以用之前i不是鏈的端點的代價來更新;反之,如果子節點與i的邊沒有翻轉,那麼就此而言i並不是端點,可要求i是鏈的乙個端點,這樣就必須用i原先就是鏈的端點的代價來更新

遍歷根節點所有子節點後,更新dp:

如果i與父親的邊沒有翻轉。即狀態dp[i][0]:

首先,i不作為鏈的端點肯定是一種可能性,直接比較

接著,如果i是鏈的乙個端點,i和父節點的邊還沒有翻轉,那麼說明在這個狀態下i是真正的奇度點,所以將狀態q的first+1後更新

如果i與父親的邊翻轉了,同樣分兩類更新:

首先,i本身作為了鏈的端點,而由於i本身就是奇度點,所以僅需將q.second+1來更新即可

還有,如果i本身在下面並沒有作為鏈的端點,而i卻與父節點的邊發生了翻轉,所以i就成為了新的奇度點,同時鏈長還增加了,所以p.first,p.second均增加即可

最後答案即為dp[1][0].first/2,dp[1][0].second

#include #include #include #include #include #include #include #include #define inf 0x3f3f3f3f

using namespace std;

struct edge

edge[200005];

int head[100005];

int cnt=1;

pair dp[100005][2];

int n;

void init()

void add(int l,int r,int w)

pairaddp(paira,pairb)

void dfs(int x,int fx,int typ)

dfs(to,x,edge[i].val);

pair temp1,temp2;

temp1=min(addp(p,dp[to][0]),addp(q,dp[to][1]));

temp2=min(addp(p,dp[to][1]),addp(q,dp[to][0]));

p=temp1;

q=temp2;

} if(typ==2||typ==0)

else

if(typ==2||typ==1)

else }

int main()

else

}dfs(1,1,0);

printf("%d %d\n",dp[1][0].first/2,dp[1][0].second);

return 0;

}

雅禮 noip2018 模擬賽day3 T2

典型的狀壓思想 設0表示黑球,1表示白球,用一串01序列代表剩下的球的狀態,記f i 表示在i狀態下取球的最大期望 那麼可以利用記憶化搜尋更新,每一層列舉可能拿走的球然後向下搜尋,同時記憶化即可 在狀態中刪去乙個點可以利用位運算實現 同時要注意乙個問題,就是狀態0010和狀態010並不是相同的狀態,...

NOIP2018模擬賽2018 10 18 輕功

description 題目背景 尊者神高達進入了基三的世界,作為乙個 mmorpg 做任務是必不可少的,然而跑地圖卻令人十分不爽。好在基三可以使用輕功,但是尊者神高達有些手殘,他決定用梅花樁練習輕功。題目描述 一共有 n 個木樁,要求從起點 0 開始,經過所有梅花樁,恰好到達終點 n,尊者神高達一...

NOIP2018模擬賽2018 10 18 開荒

description 題目背景 尊者神高達作為乙個萌新,在公升級路上死亡無數次後被乙隻大黃嘰帶回了師門。他加入師門後發現有無窮無盡的師兄弟姐妹,這幾天新副本開了,尊者神高達的師門作為乙個 pve師門,於是他們決定組織一起去開荒。題目描述 師門可以看做以 1 為根的一棵樹,師門中的每乙個人都有一定的...