着色方案
[SCOI2008]着色方案
https://ac.nowcoder.com/acm/problem/20265
对于每种油漆,如果它能涂的数量相同,那对结果贡献就是相同的,所以,用dp[a][b][c][d][e][las],a,b,c,d,e表示还能涂1,2,3,4,5个木块,las表示上一次涂的是哪一种剩余量的油漆。
假如上一次涂的是剩余量为2的油漆
如果当前 a 还有剩余,那么最终结果应该加上:
( a - 1 )dp[a-1][b][c][d][e][1]
(因为上一次涂的是剩余量为2的油漆(b),涂完之后,剩余量为1的油漆就会多一个,因此这里是 a - 1 )
如果b还有剩余 那么应该加上:
bdp[a+1][b-1][c][d][e][2]
(b还有剩余,就涂一个b,然后a就多了一个)
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f #define mod 1000000007 using namespace std; ll n,m,dp[17][17][17][17][17][7],vis[17]; ll dfs(int a, int b, int c, int d, int e, int las) { if(a+b+c+d+e==0) return 1; ll ans=0; if(dp[a][b][c][d][e][las]) return dp[a][b][c][d][e][las]; if(a) ans=(ans+ (a-(las==2))*dfs(a-1,b,c,d,e,1) ); if(b) ans=(ans+ (b-(las==3))*dfs(a+1,b-1,c,d,e,2) ); if(c) ans=(ans+ (c-(las==4))*dfs(a,b+1,c-1,d,e,3) ); if(d) ans=(ans+ (d-(las==5))*dfs(a,b,c+1,d-1,e,4) ); if(e) ans=(ans+ e*dfs(a,b,c,d+1,e-1,5) ); return dp[a][b][c][d][e][las]=ans%mod; } int main () { ll T,i,t,j,k,p,sum=0; cin>>k; for(i=0;i<k;++i){ cin>>p; vis[p]++; } sum=dfs(vis[1],vis[2],vis[3],vis[4],vis[5],0); cout<<sum<<endl; return 0; }