作为dp题并不难,关键是注意写法。不需要先判断是否与前一行和后一行冲突,因为最后相加的时候冲突的是被排除出去的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 20
using namespace std;
char s[MAX],board[MAX][MAX];
long long dp[MAX][MAX];
int main(){
while(cin>>s){
memset(board,0,MAX*MAX);
memset(dp,0,MAX*MAX*8);
int len=strlen(s);
long long ans=0;
for(int i=0;i<len;i++){
if(s[i]!='?'){
int num;
if(s[i]>='0'&&s[i]<='9')
num=s[i]-'0';
else
num=s[i]-'A'+10;
board[i+1][num]=1,board[i+1][0]=num;
}
}
if(board[1][0]>0){
dp[1][board[1][0]]=1;
}
else{
for(int i=1;i<=len;i++)
dp[1][i]=1;
}
for(int i=2;i<=len;i++){
if(board[i][0]>0){
for(int j=1;j<=len;j++){
if(abs(j-board[i][0])>1)
dp[i][(int)board[i][0]]+=dp[i-1][j];
}
continue;
}
for(int j=1;j<=len;j++){
//if(!(j-1>=1&&board[i-1][j-1]==1)&&!(j+1<=len&&board[i-1][j+1]==1)&&board[i-1][j]==0&&!(j-1>=1&&board[i+1][j-1]==1)&&!(j+1<=len&&board[i+1][j+1]==1)&&board[i+1][j]==0){
for(int t=1;t<=len;t++){
if(abs(t-j)>1)
dp[i][j]+=dp[i-1][t];
}
//}
}
}
for(int i=1;i<=len;i++)
ans+=dp[len][i];
cout<<ans<<endl;
next:{}
}
return 0;
}