现在的位置: 首页 > 综合 > 正文

【bzoj 1079】: [SCOI2008]着色方案

2017年04月26日 ⁄ 综合 ⁄ 共 1644字 ⁄ 字号 评论关闭

http://www.lydsy.com/JudgeOnline/problem.php?id=1079

看了范围以为是搜索,直到我发现了“即方案总数模1,000,000,007的结果。

一类不容易想到状态的DP,和ZJOI???有点像,比那个简单就是了

看了题解的状态表示,我自己写了个dp,结果写错了。。。。。

我好弱啊啊啊啊啊啊啊啊啊

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
    int r=0,k=1;char c=getchar();
    for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
    for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
    return k*r;
}
/////////////////////////////////////////////////
#define mod 1000000007;
int n,k;
int c[6];
LL dp[16][16][16][16][16][6];//前i个 a,b,c,e,d 
/////////////////////////////////////////////////
LL DP(int a,int b,int c,int d,int e,int k)
{
	LL &ans=dp[a][b][c][d][e][k];
	if(~ans) return ans;
	if(a+b+c+d+e==0) return ans=1;
	ans=0;
	if(a) ans+=(a-(k==2))*DP(a-1,b,c,d,e,1);
	if(b) ans+=(b-(k==3))*DP(a+1,b-1,c,d,e,2);
	if(c) ans+=(c-(k==4))*DP(a,b+1,c-1,d,e,3);
	if(d) ans+=(d-(k==5))*DP(a,b,c+1,d-1,e,4);
	if(e) ans+=(e)*DP(a,b,c,d+1,e-1,5);
	return ans%=mod;
}
/////////////////////////////////////////////////
void input()
{
    k=getint();
    int x;
    rep(i,1,k) x=getint(),c[x]++;
}
void solve()
{
	MS(dp,-1);
	printf("%lld\n",DP(c[1],c[2],c[3],c[4],c[5],0));
}
/////////////////////////////////////////////////
int main()
{
    #ifndef _TEST
    freopen("std.in","r",stdin); freopen("std.out","w",stdout);
    #endif
    input(),
    solve();
    return 0;
}

抱歉!评论已关闭.