这道题还是比较容易能看得出是dp的。但是这个状态设计我不会,参考了大佬们的题解。
这个状态的设计需要考虑到:由于每个格子的状态和前后都有关,所以,单纯一个维度是不足以准确表示状态然后进行状态转移的。俗话说得好:表达不准确?再来一维(我自己编的23333),我们可以考虑多维表示状态。
因为想到:我们要确定一个格子的状态,我们还需要的就是前一个格子的信息,因此,前一个格子需要记录自己的信息。另外,这个格子的信息还和后一个格子有关,所以,还需要一个维度表示后对后一个一个格子的要求.自然的,格子本身的位置需要记录下,因此,我们考虑开这样一个三维数组,定义状态:
dp[i][j][k]:
i表示位置。
若j==1,则自己带火,若j==0,则自身没火
若k==1,则下一格带火,否则,下一格不带火
然后,根据题目要求进行状态转移就行了。
另外,还要注意下初始条件的设置,这点也比较麻烦。
最重要的,记得mod
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) #define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=1e6+10; int dp[maxn][2][2]={0}; char str[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== scanf("%s",str+1); int len=strlen(str+1); if(str[1]=='*'){ dp[0][0][1]=1; } else if(str[1]=='?'){ dp[0][0][1]=1; dp[0][0][0]=1; } else{ dp[0][0][0]=1; } rep(i,1,len){ if(str[i]=='0'){ dp[i][0][0]=(dp[i-1][0][0])%mod; } if(str[i]=='1'){ dp[i][0][1]=(dp[i-1][0][0])%mod; dp[i][0][0]=(dp[i-1][1][0])%mod; } if(str[i]=='2'){ dp[i][0][1]=(dp[i-1][1][0])%mod; } if(str[i]=='*'){ dp[i][1][1]=(dp[i][1][0]=dp[i-1][1][1]+dp[i-1][0][1])%mod; } if(str[i]=='?'){ dp[i][1][0]=dp[i][1][1]=(dp[i-1][1][1]+dp[i-1][0][1])%mod; dp[i][0][0]=dp[i][0][1]=(dp[i-1][0][0]+dp[i-1][1][0])%mod; } } write((dp[len][0][0]+dp[len][1][0])%mod); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }