2020級訓練賽10 22

2021-09-28 21:01:56 字數 2190 閱讀 2263

點此看題

0x01 樹形dp

我一開始想寫樹形dpdp

dp,結果寫不出來。

其實這道題dpdp

dp也是可以的,定義dp[

u][i

]dp[u][i]

dp[u][

i]為離u

uu最近的被標記點距離為i

ii,然後處理完子樹u

uu的最小花費。

轉移就不詳細講了,相信你自己能yyyy

yy(比如用一些奇技淫巧 )出來。

0x02 貪心

我們跑一遍這棵樹,在回溯的時候存下離它最近的標記點和最遠的未標記點,如果未標記點再回溯就不可能在被標記,那就在當前點標記它,這其實是一種」能拖就拖「的貪心方法,因為標記最上面的點能涉及到的範圍最廣,也就最優,時間複雜度只有o(n

)o(n)

o(n)

#include

#include

using

namespace std;

const

int maxn =

10005

;int

read()

int n,tot,ans,f[maxn]

;struct edgee[2

*maxn]

;struct node

;node dfs

(int u,

int fa)

if(max==2)

;}if(max+min<=2)

return node

;return node;}

intmain()

,f[i]

=tot;

e[++tot]

=edge

,f[j]

=tot;

} node t=

dfs(1,

0);if

(t.x) ans++

;printf

("%d\n"

,ans)

;}

點此看題

其實本題一看就是樹形dpdp

dp的題,可是狀態的不確定性實在太大了,普通的樹dpdp

dp根本做不了。

考慮每個葉節點對答案的影響,發現每個葉節點只對該點到根節點的路徑上的決策有直接影響,而因為我們的樹是乙個完全二叉數,且深度為n

nn,所以我們在樹dpdp

dp中暴枚每條鏈的所有可能只會消耗o(2

n−1)

o(2^)

o(2n−1

),這樣我們就把樹上非葉節點的狀態確定了。

然後我們考慮確定葉節點的狀態,把它放進dpdp

dp式中,定義f[i

][j]

f[i][j]

f[i][j

]為第i

ii個點的子樹內的葉節點有j

jj個點參軍,然後跑揹包即可,注意我們樹dpdp

dp時用了暴力列舉可能性,f

ff陣列要清零。

每一層算複雜度,可得o(n

22n−

4)

o(n2^)

o(n22n

−4)

#include

#include

using

namespace std;

const

int maxn =

1025

;int

read()

int n,m,max,vis[10]

,a[maxn][10

],b[maxn][10

],f[maxn]

[maxn]

;void

dfs(

int u,

int y)

for(

int k=

0;k<=

1;k++)}

intmain()

for(

int i=

1<1<1;i++

)dfs(1

,n);

for(

int i=

0;i<=m;i++

) max=

max(max,f[1]

[i])

;printf

("%d\n"

,max)

;}

2020藍橋杯訓練賽 二

1 9的數字可以組成3個3位數,設為 a,b,c,現在要求滿足如下關係 b 2 a c 3 a 請你寫出a的所有可能答案,數字間用空格分開,數字按公升序排列。注意 只提交a的值,嚴格按照格式要求輸出。列舉遍歷,滿足要求的a只會在123 333範圍內,只要檢查一下a情況下,b,c是否全部符合題意,這裡...

訓練 9 13 訓練賽

a.hdu 6230 乙個合法的子串 s 3n 2 滿足條件即1 2n 1 為以n為回文中心的回文串,n 3n 2為以2n 1為中心的回文串。故我們可以通過尋找回文中心對,來判斷相應合法子串的個數。利用manacher求出每個位置的最長回文半徑,則若i,j滿足條件 i j 則應有 p i geqsl...

訓練賽 詠歎

安師大附中訓練題目 給定乙個1到n的排列a,對其進行氣泡排序 counter 0 while a不是公升序的 counter counter 1 for i 1 to n 1 if a i a i 1 then swap a i a i 1 endifend forend while那麼經過幾輪排序...