您的位置:首页 > 其它

[bzoj1079][SCOI2008]着色方案

2017-03-15 18:39 375 查看
有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。

所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两

个相邻木块颜色不同的着色方案。 k<=15,c<=5

f[a][b][c][d][e][l] a-e表示剩余1-5个块的颜色的数量,l表示上一个选的颜色,记忆化搜索。

#include<iostream>
#include<cstdio>
#define mod 1000000007
#define ll long long
#define g f[s1][s2][s3][s4][s5][last]
using namespace std;
inline int read()
{
int 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];
int c[16],K,num[6];

ll dfs(int s1,int s2,int s3,int s4,int s5,int last)
{
if(g)return g;
if(s1)g+=(s1-(last==1))*dfs(s1-1,s2,s3,s4,s5,0);
if(s2)g+=(s2-(last==2))*dfs(s1+1,s2-1,s3,s4,s5,1);
if(s3)g+=(s3-(last==3))*dfs(s1,s2+1,s3-1,s4,s5,2);
if(s4)g+=(s4-(last==4))*dfs(s1,s2,s3+1,s4-1,s5,3);
if(s5)g+=s5*dfs(s1,s2,s3,s4+1,s5-1,4);
g%=mod;
return g;
}

int main()
{
K=read();for(int i=1;i<=K;i++)c[i]=read(),num[c[i]]++;
for(int i=0;i<5;i++)f[0][0][0][0][0][i]=1;
cout<<dfs(num[1],num[2],num[3],num[4],num[5],0);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: