这道题是没有思路的,主要是学习了别人的题解,主要的思路就是动态规划。关于dp类型题目的一个归纳可以参考 https://www.hello-algo.com/chapter_dynamic_programming/dp_solution_pipeline/ 其中提到该类问题的特点: 1.先观察问题是否适合使用回溯(穷举)解决。适合用回溯解决的问题通常满足“决策树模型”,这种问题可以使用树形结构来描述,其中每一个节点代表一个决策,每一条路径代表一个决策序列。 2. 问题包含最大(小)或最多(少)等最优化描述。 3. 问题的状态能够使用一个列表、多维矩阵或树来表示,并且一个状态与其周围的状态存在递推关系。 4. 问题的目标是找出所有可能的解决方案,而不是找出最优解。 5. 问题描述中有明显的排列组合的特征,需要返回具体的多个方案。 了解了dp的基本思路,回头看这道题,主要是定义方程dp[N][0][1]=1,表示处理第N行的数字,其中0可以表示0表示这一行没有雷,1表示n+1行有雷。 等号后面的1表示方案数。 初始化之后,之后对应的情况就可以不断累加。

using namespace std;
int main(){

    const int N=10000+5;
    int n, dp[N][2][2] = {}, a, ans = 0; // 显式初始化
    cin>>n;
    dp[0][0][0]=1;dp[0][0][1]=1; // 表示第一行为0,1的方案数量为1 初始化 DP 数组
    for(int i=1;i<=n;i++){
        cin >> a; //临时变量
        if(a==3){ //相当于只有一种可能,i行的方案数量直接就是i-1移动过来
            dp[i][1][1]+=dp[i-1][1][1];
        }
        if(a==2)
        {
            dp[i][1][1]+=dp[i-1][0][1];
            dp[i][1][0]+=dp[i-1][1][1];
            dp[i][0][1]+=dp[i-1][1][0];
        }
        if(a==1)
        {
            dp[i][1][0]+=dp[i-1][0][1];
            dp[i][0][1]+=dp[i-1][0][0];
            dp[i][0][0]+=dp[i-1][1][0];
        }
        if(a==0)
        {
            dp[i][0][0]+=dp[i-1][0][0];
        }

    }
        ans+=dp[n][0][0]+dp[n][1][0];
        cout<<ans<<endl;
        return 0;
}