题解 P2476 【[SCOI2008]着色方案】

多维dp+暴力记搜

Solution1

显然是一个计数dp,但是状态的存储很难想到:\(f[a_1][a_2][a_3][a_4][a_5][last]\) 表示第 \(i\) 种颜色还剩 \(a_i\) 个时,当前木块颜色为 \(last\) 的方案数。考虑记搜,即 \(f[a_1][a_2][a_3][a_4][a_5][last]\) 是从少一个木块的状态转移来的,那么分别考虑上一个木块的颜色为 \(1-5\) 即可转移。

转移方程:如果上一个是颜色 \(i\),就要从 \(f[...][a_{i-1}+1][a_i-1][...][last]\) 转移,并且考虑其相同颜色的顺序不同,还要乘上 \(\begin{cases}a_i-1&last=a_i\\a_i&last\not=a_i\end{cases}\)

Code

注意勤取模(

#include<bits/stdc++.h>
using namespace std;
const int P=1e9+7;
int n,f[17][17][17][17][17][7],tot,cnt[17];
#define val f[a][b][c][d][e][las]
int dfs(int a,int b,int c,int d,int e,int las){
	if(val!=-1)return val;
	if(a+b+c+d+e==0)return 1;
	int res=0;
	if(a)(res+=1ll*dfs(a-1,b,c,d,e,1)*(a-(las==2))%P)%=P;
	if(b)(res+=1ll*dfs(a+1,b-1,c,d,e,2)*(b-(las==3))%P)%=P;
	if(c)(res+=1ll*dfs(a,b+1,c-1,d,e,3)*(c-(las==4))%P)%=P;
	if(d)(res+=1ll*dfs(a,b,c+1,d-1,e,4)*(d-(las==5))%P)%=P;
	if(e)(res+=1ll*dfs(a,b,c,d+1,e-1,5)*e%P)%=P;
	return val=res;
}
int main(){
	scanf("%d",&n);
	for(int i=1,x;i<=n;i++)
		scanf("%d",&x),cnt[x]++;
	memset(f,-1,sizeof(f));
	printf("%d\n",dfs(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0));
	return 0;
}
posted @ 2020-12-10 23:06  ADay526  阅读(183)  评论(0)    收藏  举报