傳送門:
題目大意:有n個木塊排成一行,從左到右依次編號為1~n。你有k種顏色的油漆,其中第i種顏色的油漆足夠塗ci個木塊。
所有油漆剛好足夠塗滿所有木塊,即c1+c2+...+ck=n。相鄰兩個木塊塗相同色顯得很難看,所以你希望統計任意兩
個相鄰木塊顏色不同的著色方案。
題解:dp,設f[a][b][c][d][e][last]表示可以使用一次的為a個,可以使用兩次的為b個,以此類推到e,last表示前乙個是可以用last次的。
為什麼要記錄last??
從dp方程可得:
if (a+b+c+d+e==0) return f[a][b][c][d][e][kind]=1;
if (f[a][b][c][d][e][kind]) return f[a][b][c][d][e][kind];
if (a) (sum+=(a-(kind==2))*calc(a-1,b,c,d,e,1))%=mod;
if (b) (sum+=(b-(kind==3))*calc(a+1,b-1,c,d,e,2))%=mod;
if (c) (sum+=(c-(kind==4))*calc(a,b+1,c-1,d,e,3))%=mod;
if (d) (sum+=(d-(kind==5))*calc(a,b,c+1,d-1,e,4))%=mod;
if (e) (sum+=e*calc(a,b,c,d+1,e-1,5))%=mod;
注釋:kind即為last!
**:
#include#includeview code#include
#include
#include
#define ll long long
#define n 6
#define mod 1000000007
using
namespace
std;
intk,sum[n],x;
int f[16][16][16][16][16][6
];ll ans;
intread()
ll calc(
int a,int b,int c,int d,int e,int
kind)
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。輸...