1. 程式人生 > >LUOGU P2476 [SCOI2008]著色方案

LUOGU P2476 [SCOI2008]著色方案

tps href 發現 技術分享 show hid main using scan

傳送門

解題思路

毒瘤題,,剛開始寫了個奇奇怪怪的哈希,結果T了5個點。。後來深(kan)入(le)思(ti)考(jie),發現c的範圍很小,設$f[a][b][c][d][e][pre]?$表示還能塗一個格子的有a個,兩個格子的有b個。。。pre表示上一個塗的顏色,轉移看代碼,比較好想。

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int MAXN = 17;
const int mod = 1e9+7;
typedef long
long LL; int k,c[MAXN],cnt[MAXN]; int f[MAXN][MAXN][MAXN][MAXN][MAXN][7]; int dfs(int a,int b,int c,int d,int e,int pre){ if(f[a][b][c][d][e][pre]) return f[a][b][c][d][e][pre]; if(!a && !b && !c && !d && !e) return f[a][b][c][d][e][pre]=1; int ret=0;
if(a) ret=(ret+(LL)(a-(pre==2))*dfs(a-1,b,c,d,e,1)%mod)%mod; if(b) ret=(ret+(LL)(b-(pre==3))*dfs(a+1,b-1,c,d,e,2)%mod)%mod; if(c) ret=(ret+(LL)(c-(pre==4))*dfs(a,b+1,c-1,d,e,3)%mod)%mod; if(d) ret=(ret+(LL)(d-(pre==5))*dfs(a,b,c+1,d-1,e,4)%mod)%mod; if(e) ret=(ret+(LL)e*dfs(a,b,c,d+1
,e-1,5)%mod)%mod; return f[a][b][c][d][e][pre]=ret; } int main(){ scanf("%d",&k); for(int i=1;i<=k;i++) scanf("%d",&c[i]),cnt[c[i]]++; printf("%d",dfs(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0)); return 0; }
View Code

LUOGU P2476 [SCOI2008]著色方案