题解 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;
}

浙公网安备 33010602011771号