loj10172
涂抹果酱
Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕。蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1 的小正方形区域(可以把蛋糕当成 NNN 行 MMM 列的矩阵)。蛋糕很快做好了,但光秃秃的蛋糕肯定不好看!所以,Sam 要在蛋糕的上表面涂抹果酱。果酱有三种,分别是红果酱、绿果酱、蓝果酱,三种果酱的编号分别为 1,2,31,2,31,2,3。为了保证蛋糕的视觉效果,Admin 下达了死命令:相邻的区域严禁使用同种果酱。但 Sam 在接到这条命令之前,已经涂好了蛋糕第 KKK 行的果酱,且无法修改。
现在 Sam 想知道:能令 Admin 满意的涂果酱方案有多少种。请输出方案数 mod106。若不存在满足条件的方案,请输出 000。
------------------------------------------------------------------------------------------------------------------------------
状态压缩动态规划
三进制状态压缩,转移方程式很简单,问题只是处在三进制的处理!
------------------------------------------------------------------------------------------------------------------------------
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int nn,n,m,k,sk; 5 long long f[10010][1<<5+5]; 6 int st[1<<5+5],js; 7 int maxm=1; 8 9 void getst() 10 { 11 for(int i=0;i<m;++i)maxm*=3; 12 for(int ii=0;ii<maxm;++ii) 13 { 14 int i=ii,bz=1; 15 int pre=-1; 16 for(int cur,j=0;j<m;++j) 17 { 18 cur=i%3; 19 if(cur==pre){ 20 bz=0; 21 break; 22 } 23 pre=cur; 24 i/=3; 25 } 26 if(bz)st[js++]=ii; 27 } 28 } 29 bool bj(int x,int y) 30 { 31 x=st[x];y=st[y]; 32 for(int i=0;i<m;++i) 33 { 34 int xx=x%3,yy=y%3; 35 if(xx==yy)return 0; 36 x/=3;y/=3; 37 } 38 return 1; 39 } 40 void dp() 41 { 42 for(int i=0;i<js;++i)f[1][st[i]]=1; 43 for(int i=2;i<=nn;++i) 44 { 45 for(int s=0;s<js;++s) 46 { 47 for(int ss=0;ss<js;++ss) 48 if(bj(ss,s))f[i][st[s]]=(f[i][st[s]]+f[i-1][st[ss]])%1000000; 49 } 50 } 51 } 52 int main() 53 { 54 scanf("%d%d%d",&n,&m,&k); 55 for(int tp,i=0;i<m;++i) 56 { 57 scanf("%d",&tp);tp--; 58 sk=sk*3+tp; 59 } 60 getst(); 61 nn=max(k,n-k+1); 62 dp(); 63 cout<<f[k][sk]*f[n-k+1][sk]%1000000; 64 return 0; 65 }