bzoj1079 SCOI2008 著色方案

2022-05-02 05:36:09 字數 1382 閱讀 9434

有n個木塊排成一行,從左到右依次編號為1~n。你有k種顏色的油漆,其中第i種顏色的油漆足夠塗ci個木塊。所有油漆剛好足夠塗滿所有木塊,即c1+c2+...+ck=n。相鄰兩個木塊塗相同色顯得很難看,所以你希望統計任意兩個相鄰木塊顏色不同的著色方案。

第一行為乙個正整數k,第二行包含k個整數c1, c2, ... , ck。

輸出乙個整數,即方案總數模1,000,000,007的結果。

31 2 3

10100%的資料滿足:1 <= k <= 15, 1 <= ci <= 5

正解:記憶化搜尋。

開始覺得這是道水題,然後越想越覺得不對勁。看題解以後感覺好神奇啊。。這個狀態怎麼想得到啊。。

我們可以考慮,如果兩種顏色剩餘次數一樣,那麼這兩種顏色其實是沒有區別的。那麼我們可以設$f[a_][a_][a_][a_][a_][last]$表示剩餘次數為$a_$的顏色有多少種,上一次是用的次數為$last$的顏色。這樣我們可以直接大力轉移,因為這種次數的有$a_$個,所以轉移的時候乘上$a_$就好。然後如果當前要用次數為$a_$的顏色,上一次用次數為$a_$的顏色,那麼這次轉移的方案數就要減一。

1

//it is made by wfj_2048~

2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include

14#define rhl (1000000007)

15#define inf (1<<30)

16#define il inline

17#define rg register

18#define ll long long

19#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

2021

using

namespace

std;

2223

//f[a1][a2][a3][a4][a5][last]表示剩餘次數為ai的顏色有多少種,上一次是用的次數為last的顏色

24 ll f[17][17][17][17][17][6

];25

int num[6

],k,x;

2627 il int

gi()

3132 il ll dfs(rg int a1,rg int a2,rg int a3,rg int a4,rg int a5,rg int

last)

4243 il void

work()

4748

intmain()

BZOJ 1079 SCOI2008 著色方案

題目 分析 一看就覺得是dp或者直接排列組合公式或者容斥?我就只想到dp的,我們用dp i j 表示前i種顏色,排列出有j對相鄰一樣顏色的方案數。當出現乙個新的顏色時,我們把這個顏色插板法插進去,我們要列舉插入的方式,可能插到相鄰顏色一樣的中間,或者不是,然後進行狀態轉移.具體看 include i...

BZOJ1079 SCOI2008著色方案 DP

只能想到 5 15 的方法。我們要利用起 ci比較小這個性質,f a b c d e last 表示有a 種顏色用了1個,b種顏色用了2個 上一次染色用的是剩餘 last 個的顏色,轉移就是f a,b,c,d,e,last a last 2 f a 1,b,c,d,e b last 3 f a 1,...

bzoj1079 SCOI2008 著色方案

有n個木塊排成一行,從左到右依次編號為1 n。你有k種顏色的油漆,其中第i種顏色的油漆足夠塗ci個木塊。所有油漆剛好足夠塗滿所有木塊,即c1 c2 ck n。相鄰兩個木塊塗相同色顯得很難看,所以你希望統計任意兩個相鄰木塊顏色不同的著色方案。第一行為乙個正整數k,第二行包含k個整數c1,c2,ck。輸...