这是一个智商检测题
状压DP。
如果你玩过扫雷,并且内心有一棵平衡树(BB数),你就会发现答案只有0,1,2共计三种。
于是法一:模拟。
答案对不对只会取决于第一个是什么。
模拟两边就好了。
#include<bits/stdc++.h>
using namespace std;
int i,j,k,m,n,ans=2,a[10001],b[10001];
void checkx()
{
for(int i=2;i<=n+1;i++)
{
b[i]=a[i-1]-b[i-1]-b[i-2];
if (!(b[i]==1||b[i]==0))
{
ans--;
break;
}
if (i==n+1&&b[i]!=0)
{
ans--;
break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
b[0]=0;
for (i=1;i<=n;i++)
cin>>a[i];
b[1]=1;
checkx();
b[1]=0;
checkx();
cout<<ans;
return 0;
}
法二:最好理解的就是动态规划。
这时可以压一位。
f(i,j,k)i表示当前位,j用01表示这一位放没有,k用01表示下一位放没有。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int a[20000]={0};
int f[20000][3][3]={0};
int n;
int main(){
read(n);
for(int i=1;i<=n;i++){
read(a[i]);
}
f[0][0][0]=1;
f[0][0][1]=1;
for(int i=1;i<=n;i++){
if(a[i]==0){
f[i][0][0]+=f[i-1][0][0];//000
}
if(a[i]==1){
f[i][0][0]+=f[i-1][1][0];//100
f[i][1][0]+=f[i-1][0][1];//010
f[i][0][1]+=f[i-1][0][0];//001
}
if(a[i]==2){
f[i][0][1]+=f[i-1][1][0];//101
f[i][1][0]+=f[i-1][1][1];//110
f[i][1][1]+=f[i-1][0][1];//011
}
if(a[i]==3)
f[i][1][1]+=f[i-1][1][1];//111
}
cout<<f[n][1][0]+f[n][0][0];
}
法三:我把它称为天选法:
#include<bits/stdc++.h>
using namespace std;
int main(){
srand( (unsigned)time( NULL ) );
cout<<rand()%3<<endl;
}
过不过得看天意。