Portal: http://www.lydsy.com/JudgeOnline/problem.php?id=1079
The main problem: There are n pieces of wood in a row, from left to right numbered 1~n. You have a k color of paint, wherein the first color of the paint is enough to tu ci a wood block.
All the paint is just enough to fill all the pieces of wood, namely c1+c2+...+ck=n. Adjacent two pieces of wood painted the same color looks very ugly, so you want to count any two
A color scheme for different colors of adjacent wood blocks.
The following: DP, set F[a][b][c][d][e][last] that can be used once for a, can use two times for B, and so on to e,last that the previous one can be used last.
Why do you want to record last??
From the DP equation you can get:
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+= (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;
Note: Kind is last!
Code:
#include <iostream>#include<algorithm>#include<cmath>#include<cstring>#include<cstdio>#definell Long Long#defineN 6#defineMoD 1000000007using namespacestd;intk,sum[n],x;intf[ -][ -][ -][ -][ -][6];ll ans; intRead () {intx=0;CharChBOOLdo{0; while(Ch=getchar (),ch<'0'|| Ch>'9')if(ch=='-') bo=1; while(x=x*Ten+ch-'0', Ch=getchar (), ch>='0'&&ch<='9'); if(BO)return-X;returnx;} LL Calc (intAintBintCintDintEintkind) {ll sum=0; if(a+b+c+d+e==0)returnf[a][b][c][d][e][kind]=1; if(F[a][b][c][d][e][kind])returnF[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, d1E4))%=MoD; if(e) (Sum+=e*calc (a,b,c,d+1, E-1,5))%=MoD; returnf[a][b][c][d][e][kind]=sum%MoD;}intMain () {k=read (); for(intI=1; i<=k; i++) X=read (), sum[x]++; Ans=calc (sum[1],sum[2],sum[3],sum[4],sum[5],0); printf ("%lld\n", ans);}
View Code
BZOJ1079: [SCOI2008] Coloring scheme