$[ SCOI 2008 ] $ 著色方案
阿新 • • 發佈:2018-09-08
++ algo 超時 做的 string += 答案 iostream line
\(\\\)
\(Description\)
給出\(K\)種顏料各自的個數\(C_i\),每一個顏料只夠塗一個格子,求將顏料用完,塗一排格子,每個格子只能塗一次的條件下,相鄰兩個格子的顏色互不相同的方案數對\(10^9+7\)取模的結果。
- \(K\in [1,15]\),\(C_i\in [1,5]\)
\(\\\)
\(Solution\)
想的map壓縮狀態量記搜掛了
想的容斥記搜求組合數排列數取反掛了
正解真是神仙計數題做的還是少,基本的思路模型還是沒有。
- 註意到顏色相同的顏料性質是一致的。
- 基於開始想的兩種方案狀態量太大,記搜也會超時,而將一類顏料看作一種之後,狀態量大大減少,相當於只有\(5\)
- 設計狀態\(f[n_1][n_2][n_3][n_4][n_5][last]\)表示,剩余個數分別為\(1\text~5\)的顏料各有幾個,上一次使用的顏料使用前剩幾個,此時到用完所有顏料的總塗色方案數。
- 搜起來就很簡單啦,直接考慮搜哪一位遞歸下去,到全是\(0\)了答案就是\(1\),搜完累計答案時,因為一類顏料是相同的,所以直接乘上該決策的可行顏料個數。
- 一些
就我會犯的zz錯誤細節要註意:- 優先判斷搜索的顏料還有沒有再考慮搜沒搜到過,否則會數組越界
- 註意到狀態設計是使用前剩幾個所以判斷可行顏料個數時,判斷時應該是上一個是否是當前\(+1\)
- \(+1-1\)的時候註意是成對存在的
不要光顧著-1
- 這樣搜索的優越性在於,他的狀態量少,代表性強,只關心相同性質的數的個數,與一些問題的精簡狀態量思想異曲同工
但就是想不到在這裏用。
\(\\\)
\(Code\)
#include<cmath> #include<cstdio> #include<cctype> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define R register #define gc getchar #define mod 1000000007ll using namespace std; typedef long long ll; inline ll rd(){ ll x=0; bool f=0; char c=gc(); while(!isdigit(c)){if(c=='-')f=1;c=gc();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();} return f?-x:x; } ll n,s[10],f[16][16][16][16][16][10]; void dfs(ll n1,ll n2,ll n3,ll n4,ll n5,ll lst){ if((n1|n2|n3|n4|n5)==0ll){f[0][0][0][0][0][lst]=1ll;return;} if(n1>0ll&&!f[n1-1][n2][n3][n4][n5][1]) dfs(n1-1,n2,n3,n4,n5,1); if(n2>0ll&&!f[n1+1][n2-1][n3][n4][n5][2]) dfs(n1+1,n2-1,n3,n4,n5,2); if(n3>0ll&&!f[n1][n2+1][n3-1][n4][n5][3]) dfs(n1,n2+1,n3-1,n4,n5,3); if(n4>0ll&&!f[n1][n2][n3+1][n4-1][n5][4]) dfs(n1,n2,n3+1,n4-1,n5,4); if(n5>0ll&&!f[n1][n2][n3][n4+1][n5-1][5]) dfs(n1,n2,n3,n4+1,n5-1,5); if(n2>0ll) (f[n1][n2][n3][n4][n5][lst]+=(n2-(lst==3))*f[n1+1][n2-1][n3][n4][n5][2])%=mod; if(n3>0ll) (f[n1][n2][n3][n4][n5][lst]+=(n3-(lst==4))*f[n1][n2+1][n3-1][n4][n5][3])%=mod; if(n4>0ll) (f[n1][n2][n3][n4][n5][lst]+=(n4-(lst==5))*f[n1][n2][n3+1][n4-1][n5][4])%=mod; if(n1>0ll) (f[n1][n2][n3][n4][n5][lst]+=(n1-(lst==2))*f[n1-1][n2][n3][n4][n5][1])%=mod; if(n5>0ll)(f[n1][n2][n3][n4][n5][lst]+=n5*f[n1][n2][n3][n4+1][n5-1][5])%=mod; } int main(){ n=rd(); for(R ll i=1;i<=n;++i) ++s[rd()]; dfs(s[1],s[2],s[3],s[4],s[5],6); printf("%lld\n",f[s[1]][s[2]][s[3]][s[4]][s[5]][6]); return 0; }
$[\ SCOI\ 2008\ ]\ $ 著色方案