bzoj 1079 着色方案
我真是弱到什么都不会了..........
想不出来了:
从c<=5中分析大概15^(5~6)比较靠谱,但我们记每个颜色拿了多少是5^15的,于是转换一下思路,我们记录可以使用1,2,3,4,5次的颜色有多少种,把可以使用的次数相同的颜色看做等价的,于是状态变少了,我们可以记忆化搜索。
f[a][b][c][d][e][last]表示可以使用1,2,3,4,5次的颜色有a,b,c,d,e种,上一次拿的是第last个等价颜色(上次可以拿last次,那么这次只能拿last-1次)
那么很容易推出转移式子,注意对于相邻位置不能是相同的颜色的设定,我们规定这次拿的等价颜色不能喝上次的等价颜色相同,于是直接在系数里面判断一下减去即可。
paint
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define maxn 20 7 #define ms 1000000007 8 using namespace std; 9 10 long long f[16][16][16][16][16][16]; 11 int sum[maxn]; 12 int n,m; 13 long long ans; 14 15 long long dfs(int a,int b,int c,int d,int e,int last) 16 { 17 long long tmp=0; 18 if (a+b+c+d+e==0) return f[a][b][c][d][e][last]=1; 19 if (f[a][b][c][d][e][last]) return f[a][b][c][d][e][last]; 20 if (a) tmp+=(a-(last==2))*dfs(a-1,b,c,d,e,1),tmp%=ms; 21 if (b) tmp+=(b-(last==3))*dfs(a+1,b-1,c,d,e,2),tmp%=ms; 22 if (c) tmp+=(c-(last==4))*dfs(a,b+1,c-1,d,e,3),tmp%=ms; 23 if (d) tmp+=(d-(last==5))*dfs(a,b,c+1,d-1,e,4),tmp%=ms; 24 if (e) tmp+=e*dfs(a,b,c,d+1,e-1,5),tmp%=ms; 25 f[a][b][c][d][e][last]=tmp; 26 return tmp; 27 } 28 29 int main() 30 { 31 scanf("%d",&m); 32 int x; 33 for (int i=1;i<=m;i++) scanf("%d",&x),sum[x]++; 34 ans=dfs(sum[1],sum[2],sum[3],sum[4],sum[5],0); 35 printf("%lld\n",ans); 36 return 0; 37 } 38 39
AC without art, no better than WA !