• BZOJ1088 [SCOI2005]扫雷Mine 动态规划


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1088


    题意概括

      扫雷。只有2行。第2行没有雷,第一行有雷。告诉你第二行显示的数组,问有几种摆放方式。


    题解

      动态规划。

      用dp[i][0][0]表示当前位置为0,前一位置为0的方案总数,

      用dp[i][0][1]表示当前位置为1,前一位置为0的方案总数,

      用dp[i][1][0]表示当前位置为0,前一位置为1的方案总数,

      用dp[i][1][1]表示当前位置为1,前一位置为1的方案总数,

      然后分各种情况转移即可。

      网上又说直接模拟的——代码比我短好多!都是大佬!Orz


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    const int N=10000+5;
    int n,a[N];
    LL dp[N][2][2];
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for (int i=1;i<=n;i++)
            if (a[i]>3)
                {printf("0");return 0;}
        if (a[1]>2||a[n]>2)
            {printf("0");return 0;}
        memset(dp,0,sizeof dp);
        if (a[1]==0)
            dp[1][0][0]=1;
        else if (a[1]==1)
            dp[1][0][0]=dp[1][0][1]=1;
        else if (a[1]==2)
            dp[1][0][1]=1;
        for (int i=2;i<=n;i++){
            int v=a[i-1];
            LL p00=dp[i-1][0][0],p01=dp[i-1][0][1],p10=dp[i-1][1][0],p11=dp[i-1][1][1];
            LL &n00=dp[i][0][0],&n01=dp[i][0][1],&n10=dp[i][1][0],&n11=dp[i][1][1];
            if (a[i]==0){
                if (v>1)
                    {printf("0");return 0;}
                if (v==1)
                    n00+=p10;
                else if (v==0)
                    n00+=p00;
            }
            else if (a[i]==1){
                if (v==3)
                    {printf("0");return 0;}
                if (v==2)
                    n10+=p11,n01+=p10;
                else if (v==1)
                    n10+=p01,n01+=p00,n00+=p10;
                else if (v==0)
                    n00+=p00;
            }
            else if (a[i]==2){
                if (v==0)
                    {printf("0");return 0;}
                if (v==1)
                    n01+=p00,n10+=p01;
                else if (v==2)
                    n11+=p01,n10+=p11,n01+=p10;
                else if (v==3)
                    n11+=p11;
            }
            else if (a[i]==3){
                if (v<2)
                    {printf("0");return 0;}
                if (v==2)
                    n11+=p01;
                else
                    n11+=p11;
            }
        }
        LL ans;
        if (a[n]==0)
            ans=dp[n][0][0];
        else if (a[n]==1)
            ans=dp[n][0][1]+dp[n][1][0];
        else 
            ans=dp[n][1][1];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    python实现简单的百度翻译
    有趣的if循环
    用python代码模拟登录网站
    解决kali中的中文乱码问题
    基于linux下的NIST数字测试(下)——测试过程
    基于linux下的NIST数字测试(上)——安装过程
    2019-2020-20199135 《网络攻防实践》第3周作业
    2019-2020-20199135 《网络攻防实践》第2周作业
    2019-2020-20199135《网络攻防实践》第1周作业
    20199135网络攻防与实践作业
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/7368230.html
Copyright © 2020-2023  润新知