zoukankan      html  css  js  c++  java
  • mine:dp

    一个小的线性dp。方法很多,八仙过海各显神通。

    我想讲一下我的:

     1 #include<cstdio>
     2 #define mod 1000000007
     3 char s[1000005];int dp[1000005][2][2],n;//是不是雷,右边有没有雷
     4 int main(){
     5     scanf("%s",s+1);
     6     for(n=1;s[n];n++);n--;
     7     dp[0][0][0]=dp[0][0][1]=1;
     8     for(int i=1;i<=n;++i)
     9         if(s[i]=='0')dp[i][0][0]=dp[i-1][0][0];
    10         else if(s[i]=='1')dp[i][0][0]=dp[i-1][1][0],dp[i][0][1]=dp[i-1][0][0];
    11         else if(s[i]=='2')dp[i][0][1]=dp[i-1][1][0];
    12         else if(s[i]=='*')dp[i][1][1]=dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;
    13         else {
    14             dp[i][0][0]=dp[i-1][0][0];//0
    15             (dp[i][0][0]+=dp[i-1][1][0])%=mod;dp[i][0][1]=dp[i-1][0][0];//1
    16             (dp[i][0][1]+=dp[i-1][1][0])%=mod;//2
    17             dp[i][1][1]=dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;//*
    18         }
    19     printf("%d
    ",(dp[n][0][0]+dp[n][1][0])%mod);
    20 }
    先扔在这里

    我的dp含义是:dp[i][this][next]表示考虑了第i位后,this和next位置上有没有雷的方案数。

    思考一下:如果你知道前面的一位是什么,这一位是什么,你就能推断出下一位是什么。

    因为在一维扫雷里只有相邻的3个格子之间有约束作用。

    所以我们来考虑dp[i][t][n]由什么转移而来:

    如果第i位是个’0‘,那么它不是雷它的前面一位不能是雷后面也不能是,则dp[i][0][0]=dp[i-1][0][0](注意文字与代码的颜色对应)

    如果是个’1‘,那么它不是雷,分2种情况:

    前面有后面没有:dp[i][0][0]=dp[i-1][1][0];

    前面没有后面有:dp[i][0][1]=dp[i-1][0][0];

    如果是个’2‘,那么它不是雷,而都有雷:dp[i][0][1]=dp[i-1][1][0];

    如果它是个雷,那么前面随意。。后面也随意。。:dp[i][1][1]=dp[i][1][0]=dp[i-1][0][1]+dp[i-1][1][1];

    如果是个问号就把上面这些状态都弄一遍就好。

    初状态dp[0][0][0]=dp[0][0][1]=1因为第0个格子上没有雷而它的右边有没有再说并不会被第0个格子限制。

    末状态dp[n][1][0]+dp[n][0][0]因为并不在意第n个格子上有没有雷(如果它不合法那么dp值为0),而第n+1个格子上没有雷。

    完毕!

  • 相关阅读:
    数学系列:数学在计算机图形学中的应用
    数学系列:数学体系概览
    Math: Fibonacci
    算法系列:电磁频谱划分
    计算机系列:CUDA 深入研究
    算法系列:寻找最大的 K 个数
    算法系列:000
    算法系列:三元组和
    算法系列:单链表逆序
    堆栈区别
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11364776.html
Copyright © 2011-2022 走看看