Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕。蛋糕俯视图是一个 $N×M$ 的矩形,它被划分成 $N×M$ 个边长为 $1×1$ 的小正方形区域(可以把蛋糕当成 $N$ 行 $M$ 列的矩阵)。蛋糕很快做好了,但光秃秃的蛋糕肯定不好看!所以,Sam 要在蛋糕的上表面涂抹果酱。果酱有三种,分别是红果酱、绿果酱、蓝果酱,三种果酱的编号分别为 $1,2,3$。为了保证蛋糕的视觉效果,Admin 下达了死命令:相邻的区域严禁使用同种果酱。但 Sam 在接到这条命令之前,已经涂好了蛋糕第 $K$ 行的果酱,且无法修改。 现在 Sam 想知道:能令 Admin 满意的涂果酱方案有多少种。请输出方案数 $\mod 10^6$。若不存在满足条件的方案,请输出 $0$。
我们设$f[i][j]$表示第$i$行状态为$j$时的方案数。
先读入数据,在读入过程中将$3^1$~$3^m$算出,用$lg[i]$表示$3^i$。
然后压缩指定行$k$的状态$s$,初始$s=0$,$now$为当前位置上的数,共$m$个,由于有$1$~$3$所以每位计算时都要减一,也就是每次计算$s*3+(now-1)$。
然后把所有可行状态算出存在$p$数组中,共$tot$个。
关于怎么算提供一个技巧,就是十进制下$x$进制(假设为$a$)的倒数第$k$位是$(a/x^k)\%x$。
注意进制是从0位开始到m-1结束。
记得初始化:
先是$memset(f,0,sizeof(f));$
也就是转移状态。
分两种,一种是当前行为$k$的,一种是不为$k$的,枚举第$i$行,上行状态为$j$,此行状态为$k$,判断上行是否与此行冲突即可。
方程如下:
最后把第$n$行所有状态累加$Mod$即可。
1 #include<bits/stdc++.h> 2 #define Mod 1000000 3 using namespace std; 4 int n,m,k,s; 5 int lg[10]; 6 int f[10005][250]; 7 int p[250],tot=0; 8 void screen(int x) 9 { 10 for (int i=0;i<=lg[x]-1;i++) 11 { 12 bool flag=0; 13 for (int j=0;j<=m-2;j++) 14 if ((i/lg[j])%3==(i/lg[j+1])%3) {flag=1;break;} 15 if (flag==0) p[++tot]=i; 16 } 17 } 18 bool check(int a,int b) 19 { 20 for (int i=0;i<=m-1;i++) if ((a/lg[i])%3==(b/lg[i])%3) return 0; 21 return 1; 22 } 23 int main() 24 { 25 s=0;lg[0]=1; 26 scanf("%d%d%d",&n,&m,&k); 27 for (int i=1;i<=m;i++) 28 { 29 int x; 30 scanf("%d",&x); 31 s=s*3+(x-1); lg[i]=lg[i-1]*3; 32 } 33 screen(m); 34 bool flag=0; 35 //for (int i=1;i<=tot;i++) cout<<p[i]<<endl; 36 for (int i=1;i<=tot;i++) if (p[i]==s) flag=1; 37 if (flag==0) {cout<<0<<endl;return 0;} 38 memset(f,0,sizeof(f)); 39 if (k==1) f[1][s]=1; 40 else for (int i=1;i<=tot;i++) f[1][p[i]]=1; 41 for (int i=2;i<=n;i++) 42 { 43 if (i!=k) 44 { 45 for (int j=1;j<=tot;j++) 46 { 47 for (int k=1;k<=tot;k++) 48 { 49 if (check(p[j],p[k])) f[i][p[j]]+=f[i-1][p[k]]; 50 f[i][p[j]]%=Mod; 51 } 52 } 53 } 54 if (i==k) 55 { 56 for (int j=1;j<=tot;j++) if (check(p[j],s)) f[i][s]+=f[i-1][p[j]]; 57 f[i][s]%=Mod; 58 } 59 } 60 int ans=0; 61 for (int i=1;i<=tot;i++) ans+=f[n][p[i]],ans%=Mod; 62 cout<<ans<<endl; 63 return 0; 64 }
原文:https://www.cnblogs.com/GaryFang/p/11042806.html