Vijos 1193 扫雷 【动态规划】
扫雷
描述
相信大家都玩过扫雷的游戏。那是在一个n*n的矩阵里面有一些雷,要你根据一些信息找出雷来。万圣节到了,“余”任过流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和他8连通的格子里面雷的数目。现在棋盘是n*2的,第一列里某些格子是雷,而第二列没有雷,如:
o 1
* 2
* 3
* 2
o 2
* 2
* 2 ('*'代表有雷,'o'代表无雷)
由于第一类的雷有可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息求第一列雷有多少中摆放方案。格式
输入格式
第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<=N<=10000)
输出格式
一个数,即第一列中雷的摆放方案数。
样例1
样例输入1
2 1 1
样例输出1
2
限制
1s
来源
NOIP2006夏令营
题目链接:
题目大意:
按照扫雷得规则,雷局为N*2的矩形,且雷只在第一列,第二列为第一列雷的分布数量。求满足第二列要求的第一列的雷的排列方案数
题目思路:
【动态规划】
f[i][j]表示第i,i+1行第一列的状态为j的方案数。j=00,01,10,11(0,1,2,3)
通过枚举第i行的第二列为0,1,2,3来转移。
初始值要枚举第一行第二列的0,1,2,3.
可以将N*2的矩阵简化为循环矩阵。
1 /**************************************************** 2 3 Author : Coolxxx 4 Copyright 2017 by Coolxxx. All rights reserved. 5 BLOG : http://blog.csdn.net/u010568270 6 7 ****************************************************/ 8 #include<bits/stdc++.h> 9 #pragma comment(linker,"/STACK:1024000000,1024000000") 10 #define abs(a) ((a)>0?(a):(-(a))) 11 #define lowbit(a) (a&(-a)) 12 #define sqr(a) ((a)*(a)) 13 #define mem(a,b) memset(a,b,sizeof(a)) 14 const double eps=1e-8; 15 const int J=10000; 16 const int mod=1000000007; 17 const int MAX=0x7f7f7f7f; 18 const double PI=3.14159265358979323; 19 const int N=10004; 20 using namespace std; 21 typedef long long LL; 22 double anss; 23 LL aans; 24 int cas,cass; 25 int n,m,lll,ans; 26 int a[N]; 27 int f[N][4]; 28 int main() 29 { 30 #ifndef ONLINE_JUDGE 31 // freopen("1.txt","r",stdin); 32 // freopen("2.txt","w",stdout); 33 #endif 34 int i,j,k; 35 double x,y,z; 36 // for(scanf("%d",&cass);cass;cass--) 37 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 38 // while(~scanf("%s",s)) 39 while(~scanf("%d",&n)) 40 { 41 mem(f,0); 42 for(i=1;i<=n;i++) 43 scanf("%d",&a[i]); 44 if(a[1]==0)f[1][0]=1; 45 if(a[1]==1)f[1][1]=f[1][2]=1; 46 if(a[1]==2)f[1][3]=1; 47 for(i=2;i<n;i++) 48 { 49 if(a[i]==0) 50 { 51 f[i][0]=f[i-1][0]; 52 } 53 if(a[i]==1) 54 { 55 f[i][0]=f[i-1][2]; 56 f[i][2]=f[i-1][1]; 57 f[i][1]=f[i-1][0]; 58 } 59 if(a[i]==2) 60 { 61 f[i][2]=f[i-1][3]; 62 f[i][1]=f[i-1][2]; 63 f[i][3]=f[i-1][1]; 64 } 65 if(a[i]==3) 66 { 67 f[i][3]=f[i-1][3]; 68 } 69 } 70 if(a[n]==0)ans=f[n-1][0]; 71 if(a[n]==1)ans=f[n-1][1]+f[n-1][2]; 72 if(a[n]==2)ans=f[n-1][3]; 73 printf("%d\n",ans); 74 } 75 return 0; 76 } 77 /* 78 // 79 80 // 81 */