FROM WOJ 2040 山賊集團

2021-09-25 19:04:16 字數 2957 閱讀 9901

sdoi2008

題面

某山賊集團在綠蔭村擁有強大的勢力,整個綠蔭村由n個連通的小村落組成,並且保證對於每兩個小村落有且僅有一條簡單路徑相連。小村落用阿拉伯數字編號為1,2,3,4,…,n,山賊集團的總部設在編號為1的小村落中。山賊集團除了老大坐鎮總部以外,其他的p個部門希望在村落的其他地方建立分部。p個分部可以在同乙個小村落中建設,也可以分別建設在不同的小村落中。每個分部到總部的路徑稱為這個部門的管轄範圍,於是這p個分部的管轄範圍可能重疊,或者完全相同。在不同的村落建設不同的分部需要花費不同的費用。每個部門可能對他的管轄範圍內的小村落收取保護費,但是不同的分部如果對同一小村落同時收取保護費,他們之間可能發生矛盾,從而損失一部分的利益,他們也可能相互合作,從而獲取更多的利益。現在請你編寫乙個程式,確定p個分部的位置,使得山賊集團能夠獲得最大的收益。

輸入

輸入檔案第一行包含乙個整數n和p,表示綠蔭村小村落的數量以及山賊集團的部門數量。

接下來n-1行每行包含兩個整數x和y,表示編號為x的村落與編號為y的村落之間有一條道路相連。(1<=x,y<=n)

接下來n行,每行p個正整數,第i行第j個數表示在第i個村落建設第j個部門的分部的花費aij。

然後有乙個正整數t,表示下面有t行關於山賊集團的分部門相互影響的代價。(0<=t<=2p)

最後有t行,每行最開始有乙個數v,如果v為正,表示會獲得額外的收益,如果v為負,則表示會損失一定的收益。然後有乙個正整數c,表示本描述涉及的分部的數量,接下來有c個數,xi,為分部門的編號(xi不能相同)。表示如果c個分部xi同時管轄某個小村落(可能同時存在其他分部也管轄這個小村落),可能獲得的額外收益或者損失的收益為的|v|。t行中可能存在一些相同的xi集合,表示同時存在幾種收益或者損失。

輸出

輸出檔案要求第一行包含乙個數ans,表示山賊集團設定所有分部後能夠獲得的最大收益。

樣例輸出

2 11 2

2 11

3 1 1

樣例輸入

5資料規模

對於40%的資料,1<=p<=6。

對於100%的資料,1<=n<=100,1<=p<=12,保證答案的絕對值不超過10^8。

sol

顯然樹形dp。

注意到dp時需要維護管轄當前節點的部門的狀態,再看看資料規模,於是想到狀壓。

設f [i

][j]

f[i][j]

f[i][j

]表示村落i

ii被j

jj這個狀態所對應的部門管轄的時候的子樹答案,可以考慮用揹包轉移:f[u

][j]

=max

f[u]

[jxo

rk]+

f[v]

[k

]f[u][j]=max

f[u][j

]=ma

xf[u

][jx

ork]

+f[v

][k]

另外,可以發現這道題所給的部門的收益資訊,可以進行一波預處理——對於每乙個組合,所有包含該組合的狀態都可以預處理出乙個收益,而f[i

][j]

f[i][j]

f[i][j

]需要被a[i

][j]

a[i][j]

a[i][j

]初始化。

**:

#include

using

namespace std;

#define int long long

#define re register

namespace base

}using

namespace base;

inline

intrd()

inline

void

write

(int x)

const

int n=

105,s=

4100

,p=15

;int n,p,t,status,cnt,first[n]

,lo[s]

,a[n]

[p],val[s]

,f[n]

[s];

struct edgee[n<<1]

;inline

void

add(

int u,

int v)

;first[u]

=cnt;

}inline

void

dfs(

int u,

int fa)

for(

int re i=status;i;i--

)f[u]

[i]+

=val[i];}

signed

main()

for(

int re i=

0;i<=p;i++

)lo[

1<=i;for

(int re i=

1;i<=n;i++

)}t=rd(

);for(

int re i=

1;i<=t;i++

) val[st]

+=v;

int re arc_st=st^status;

for(

int re j=arc_st;j;j=

(j-1

)&arc_st)val[st|j]

+=v;

}dfs(1

,0);

write

(f[1

][status]);

exit(0

);}

204 計數質數

統計所有小於非負整數 n 的質數的數量。示例 輸入 10 輸出 4 解釋 小於 10 的質數一共有 4 個,它們是 2,3,5,7 這個題目思路很簡單,但是可能效率不高,裡面有一些小trick需要注意,所以在這裡記錄一下優化過程。思路1 逐個判斷每個數是否質數,超時 class solution d...

204 計數質數

統計所有小於非負整數 n 的質數的數量。示例 輸入 10 輸出 4 解釋 小於 10 的質數一共有 4 個,它們是 2,3,5,7 判斷質數的常規解法 如判斷n是否為質數,只需要判斷n是否能整除2 int sqrt n 厄拉多塞篩法 比如說求20以內質數的個數,首先0,1不是質數.2是第乙個質數,然...

204 計數質數

統計所有小於非負整數 n 的質數的數量。示例 輸入 10 輸出 4 解釋 小於 10 的質數一共有 4 個,它們是 2,3,5,7 埃拉託色尼篩選法,迴圈中置對應值的倍數為0,最後統計為1的個數,也就是質數的個數。class solution def countprimes self,n int i...