https://www.luogu.org/problem/show?pid=2327
借鑑了一位dalao(@xyz32768)(洛谷)的題解
設一個四維數組f[i][0/1][0/1][0/1],分別表示第i個,i-1個是否有地雷,i個是否有地雷,i+1個是否有地雷。
當a=0時(如圖)
圖1
此時只有一種情況:
也就是f[i][0][0][0]=f[i-1][0][0][0]+f[i-1][1][0][0]。
當a=1時,如下圖所示:
此時,有三種情況:
即:
f[i][1][0][0]=f[i-1][0][1][0]+f[i-1][1][1][0]
f[i][0][1][0]=f[i-1][0][0][1]+f[i-1][1][0][1],
f[i][0][0][1]=f[i-1][0][0][0]+f[i-1][1][0][0]。
其他兩種情況詳見代碼。
邊界條件是f[0][0][0][0] = f[0][0][0][1] =1(這兩種情況下都只有一種)
此外,結果取決於最後一個數字。如果該數字爲0,說明答案是f[n][0][0][0];爲1,則爲f[n][1][0][0]與f[n][0][1][0]之和。其他兩種情況見代碼。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int f[10005][2][2][2];
inline int read(){
int res = 1,x = 0;
char ch = 0;
while(ch<'0'||ch>'9'){
if (ch=='-')
res = -1;
ch = getchar();
}
while(ch>='0'&&ch<='9'){
x = (x<<3) + (x<<1) + ch - 48;
ch = getchar();
}
return x*res;
}
int main(){
int n = read();
int a;
f[0][0][0][0] = f[0][0][0][1] = 1;
for (int i =1;i<=n;i++){
a = read();
switch(a){
case 0:
f[i][0][0][0] = f[i-1][0][0][0] + f[i-1][1][0][0];
break;
case 1:
f[i][1][0][0] = f[i-1][0][1][0] + f[i-1][1][1][0];
f[i][0][1][0] = f[i-1][0][0][1] + f[i-1][1][0][1];
f[i][0][0][1] = f[i-1][0][0][0] + f[i-1][1][0][0];
break;
case 2:
f[i][1][1][0] = f[i-1][0][1][1] + f[i-1][1][1][1];
f[i][1][0][1] = f[i-1][0][1][0] + f[i-1][1][1][0];
f[i][0][1][1] = f[i-1][0][0][1] + f[i-1][1][0][1];
break;
case 3:
f[i][1][1][1] = f[i-1][0][1][1] + f[i-1][1][1][1];
break;
}
}
int ans;
if (a == 0) ans = f[n][0][0][0];
if (a == 1) ans = f[n][1][0][0] + f[n][0][1][0];
if (a == 2) ans = f[n][1][1][0];
if (a == 3) ans = 0;
cout<<ans<<endl;
return 0;
}