有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案。
标签:des blog io ar os 使用 sp for on
有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案。
第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck。
输出一个整数,即方案总数模1,000,000,007的结果。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<deque> #include<set> #include<map> #include<ctime> #define LL long long #define inf 0x7ffffff #define pa pair<int,int> #define pi 3.1415926535897932384626433832795028841971 #define mod 1000000007 using namespace std; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } LL f[16][16][16][16][16][6]; bool mrk[16][16][16][16][16][6]; int rep[6]; int n; inline LL cal(int a1,int a2,int a3,int a4,int a5,int from) { if (mrk[a1][a2][a3][a4][a5][from])return f[a1][a2][a3][a4][a5][from]; if (a1+a2+a3+a4+a5==0)return 1; LL ans=0; if (a1)ans+=(a1-(from==2))*cal(a1-1,a2,a3,a4,a5,1); if (a2)ans+=(a2-(from==3))*cal(a1+1,a2-1,a3,a4,a5,2); if (a3)ans+=(a3-(from==4))*cal(a1,a2+1,a3-1,a4,a5,3); if (a4)ans+=(a4-(from==5))*cal(a1,a2,a3+1,a4-1,a5,4); if (a5)ans+=a5*cal(a1,a2,a3,a4+1,a5-1,5); ans%=mod; mrk[a1][a2][a3][a4][a5][from]=1; f[a1][a2][a3][a4][a5][from]=ans; return f[a1][a2][a3][a4][a5][from]; } int main() { n=read(); for (int i=1;i<=n;i++)rep[read()]++; printf("%lld\n",cal(rep[1],rep[2],rep[3],rep[4],rep[5],0)); }
标签:des blog io ar os 使用 sp for on
原文地址:http://www.cnblogs.com/zhber/p/4137348.html