zoukankan      html  css  js  c++  java
  • 8.16题解

    T1

    废物除了搜索啥都不会打,连个垃圾DP都推不出来,事实上知道他是DP之后,依旧打了很久,我的DP状态和大家都不太一样,比较清奇,不过我觉得很好想,$dp[i][j][k]$表示第$i$位上为$k$前一位上为$j$的方案数,$j$和$k$均在$0 hicksim3$的范围内,$0$ $1$ $2$参照题面,$3$代表此处有雷

    思考

    先来思考一下在大多数情况下那些方案对于相邻两位是合法的

    00 两位上均没有雷且相邻位置上也没有雷
    01 两位上均没有雷,后一个位置的相邻位置上有一个位置有雷,显然是右边
    10 两位上均没有雷,前一个位置的相邻位置上有一个位置有雷,显然是左边
    11 两位上均没有雷,且两个位置的相邻位置上都有一个位置有雷,显然左边一个右边一个
    13 前一位上没雷,后一位上有雷
    23 前一位左右两侧都有雷,后一位肯定是个雷
    前一位是个雷,一共三种情况
    31    32    33

    初始化

    由于$dp$定义的特殊性,我的初始化非常麻烦,直接初始化$dp[2]$,判断一下第一二位可能出现的情况,后面就直接从$dp[3]$开始转移即可

    如果第一二位上均为$?$,那么我们只需要排除上面提到的9种情况中不合法的

    10 上面有提到他需要前一位的左边有雷,但是第一位已经是最左,所以不合法
    11 同上,第一位左侧不可能有雷
    23 同上,左侧无雷

    如果只有第一位是$?$,第二位已知直接就按照第二位,判断第一位可能情况即可

    else if(a[1]==4)//4代表该处为?
    {
        //当前为0,在上述的可能情况中选择,第一位只能为0
        if(a[2]==0)  dp[2][0][0]=1ll*1;
        //两种情况均可,对于前一种,第三位肯定是个3,当然,这是后话
        if(a[2]==1)  {dp[2][0][1]=1ll*1;  dp[2][3][1]=1ll*1;}
        //第二位为2,第一位肯定是个雷
        if(a[2]==2)  dp[2][3][2]=1ll*1;
        //第二位有个雷,第一位要么是个雷,要么不是雷那他的相邻位置上就必须标记有雷
        //注意23状态对于前两位,已经被判不合法
        if(a[2]==3)  {dp[2][1][3]=1ll*1;  dp[2][3][3]=1ll*1;}
    }

    同理判断只有第二位为$?$的情况,可以自己思考一下

    else if(a[2]==4)
    {
        if(a[1]==0)  {dp[2][0][0]=1ll*1;  dp[2][0][1]=1ll*1;}
        if(a[1]==1)  dp[2][1][3]=1ll*1;
        if(a[1]==3)  {dp[2][3][1]=1ll*1;  dp[2][3][2]=1ll*1;  dp[2][3][3]=1ll*1;}
    }

    两位都不为$?$要么不合法,要么就直接用,由于数据里没有不合法,所以我没判,严谨一点的话是需要判的

    状态转移

    当然又是一个长篇大论的分情况讨论,我们用$dp[i-1]$更新$dp[i]$

    假设第$i$个位置上是0,由最初状态,状态只能是$00$或$10$,考虑这两种状态分别由哪些状态转移得来的,可以在列出的状态中选择合法状态,$00$可以由$00$和$10$转移得来,注意$dp[i]$的第二维和$dp[i-1]$的第三维之间的对应关系

    第$i$个位置上为1,合法状态有$01$ $11$ $31$,$01$可以由$10$和$00$转移来,$11$由$31$转移来,$31$由$13$ $23$ $33$转移来

    第$i$个位置为2或3时的状态转移可以自己想一想,想过之后去我的标程里对照一下,为5的时候就把前面的情况全和起来就可以了,我才不承认我是因为懒才没写全的

    对于这种大量分情况讨论的题,转移的过程中一定要注意方案的合法性,保证补充不漏

    统计答案

    排除对最后一位来说的不合法状态即可

    01 右侧不可能再出现雷
    11 同上,右侧无雷
    32 同上,右侧无雷
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define maxn 1001000
     5 #define ll long long
     6 #define mod 1000000007
     7 using namespace std;
     8 int n;
     9 ll ans;
    10 int a[maxn];
    11 char s[maxn];
    12 ll dp[maxn][5][5];
    13 int main()
    14 {
    15     scanf("%s",s);  n=strlen(s);
    16     for(int i=1;i<=n;++i)
    17     {
    18         if(s[i-1]=='0')  a[i]=0;
    19         else if(s[i-1]=='1')  a[i]=1;
    20         else if(s[i-1]=='2')  a[i]=2;
    21         else if(s[i-1]=='*')  a[i]=3;
    22         else  a[i]=4;
    23     }
    24     if(a[1]==4&&a[2]==4)
    25     {
    26         dp[2][0][0]=1ll*1;  dp[2][0][1]=1ll*1;  dp[2][1][3]=1ll*1;
    27         dp[2][3][1]=1ll*1;  dp[2][3][2]=1ll*1;  dp[2][3][3]=1ll*1;
    28     }
    29     else if(a[1]==4)
    30     {
    31         if(a[2]==0)  dp[2][0][0]=1ll*1;
    32         if(a[2]==1)  {dp[2][0][1]=1ll*1;  dp[2][3][1]=1ll*1;}
    33         if(a[2]==2)  dp[2][3][2]=1ll*1;
    34         if(a[2]==3)  {dp[2][1][3]=1ll*1;  dp[2][3][3]=1ll*1;}
    35     }
    36     else if(a[2]==4)
    37     {
    38         if(a[1]==0)  {dp[2][0][0]=1ll*1;  dp[2][0][1]=1ll*1;}
    39         if(a[1]==1)  dp[2][1][3]=1ll*1;
    40         if(a[1]==3)  {dp[2][3][1]=1ll*1;  dp[2][3][2]=1ll*1;  dp[2][3][3]=1ll*1;}
    41     }
    42     else  dp[2][a[1]][a[2]]=1ll*1;
    43     for(int i=3;i<=n;++i)
    44     {
    45         if(a[i]==0)
    46         {
    47             dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
    48             dp[i][1][0]=dp[i-1][3][1];
    49         }
    50         else if(a[i]==1)
    51         {
    52             dp[i][0][1]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
    53             dp[i][1][1]=dp[i-1][3][1];
    54             dp[i][3][1]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    55         }
    56         else if(a[i]==2)
    57             dp[i][3][2]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    58         else if(a[i]==3)
    59         {
    60             dp[i][1][3]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;
    61             dp[i][2][3]=dp[i-1][3][2];
    62             dp[i][3][3]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    63         }
    64         else
    65         {
    66             dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
    67             dp[i][1][0]=dp[i-1][3][1];
    68             dp[i][0][1]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
    69             dp[i][1][1]=dp[i-1][3][1];
    70             dp[i][3][1]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    71             dp[i][3][2]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    72             dp[i][1][3]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;
    73             dp[i][2][3]=dp[i-1][3][2];
    74             dp[i][3][3]=((dp[i-1][1][3]+dp[i-1][2][3])%mod+dp[i-1][3][3])%mod;
    75         }
    76     }
    77     ans=((ans+dp[n][0][0])%mod+dp[n][1][0])%mod;
    78     ans=((ans+dp[n][3][1])%mod+dp[n][1][3])%mod;
    79     ans=((ans+dp[n][2][3])%mod+dp[n][3][3])%mod;
    80     printf("%lld
    ",ans);
    81     return 0;
    82 }
    超长分类讨论

    T2

    考试结束前三分钟,觉得可以和图论扯在一起,然而晚了

    对于一个格子里水,他一定是沿着一条最矮的路流出去的,那么我们可以给相邻两点之间建边,以两点中的较大高度为边权,给最外面一圈点和外界连边,然后跑最小生成树,这样跑出来的就是最矮的一条路,也就是使所有点流出去的一条路,然后再$dfs$一遍,找到每个点流出去的路径上边权最大的边更新当前点的答案,因为一定是路径上最高的点限制了水流出去

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdio>
     4 #define maxn 310
     5 #define bh(i,j) ((i-1)*m+j)
     6 using namespace std;
     7 struct node{
     8     int from,to,w;
     9 }a[maxn*maxn*4];
    10 int n,m,tot,js;
    11 int fa[maxn*maxn];
    12 int head[maxn*maxn],to[maxn*maxn*8],xia[maxn*maxn*8],w[maxn*maxn*8];
    13 int pd[maxn*maxn],ans[maxn*maxn];
    14 int b[maxn][maxn];
    15 int find(int x)
    16 {
    17     if(fa[x]!=x)  return fa[x]=find(fa[x]);
    18     return fa[x];
    19 }
    20 void add(int x,int y,int z)
    21 {
    22     to[++js]=y;  xia[js]=head[x];  w[js]=z;  head[x]=js;
    23 }
    24 bool cmp(const node &a,const node &b)
    25 {
    26     return a.w<b.w;
    27 }
    28 void me(int x,int y)
    29 {
    30     x=find(x);  y=find(y);
    31     fa[y]=x;
    32 }
    33 void dfs(int x)
    34 {
    35     pd[x]=1;
    36     for(int i=head[x];i;i=xia[i])
    37     {
    38         int ls=to[i];
    39         if(!pd[ls])  {ans[ls]=max(ans[x],w[i]);  dfs(ls);}
    40     }
    41 }
    42 int main()
    43 {
    44 //    freopen("2.in","r",stdin);
    45 //    freopen("WA.out","w",stdout);
    46     scanf("%d%d",&n,&m);
    47     for(int i=1;i<=n;++i)
    48     {
    49         for(int j=1;j<=m;++j)
    50         {
    51             scanf("%d",&b[i][j]);
    52             if(i==1||i==n||j==1||j==m)
    53                 {a[++tot].from=0;  a[tot].to=bh(i,j);  a[tot].w=max(0,b[i][j]);}
    54             if(i-1>=1)
    55             {
    56                 a[++tot].from=bh(i-1,j);  a[tot].to=bh(i,j);
    57                 a[tot].w=max(b[i][j],b[i-1][j]);
    58             }
    59             if(j-1>=1)
    60             {
    61                 a[++tot].from=bh(i,j-1);  a[tot].to=bh(i,j);
    62                 a[tot].w=max(b[i][j],b[i][j-1]);
    63             }
    64         }
    65     }
    66     for(int i=0;i<=n*m;++i)  fa[i]=i;
    67     int tt=0;
    68     sort(a+1,a+tot+1,cmp);
    69     for(int i=1;i<=tot;++i)
    70     {
    71         int fo=a[i].from,t=a[i].to;
    72         if(find(fo)!=find(t))
    73         {
    74             me(fo,t);  add(fo,t,a[i].w);  add(t,fo,a[i].w);
    75             tt++;
    76             if(tt==n*m)  break;
    77         }
    78     }
    79     for(int i=0;i<=n*m+10;++i)  ans[i]=-1000000100;
    80     dfs(0);
    81     for(int i=1;i<=n;++i)
    82     {
    83         for(int j=1;j<=m;++j)  printf("%d ",max(0,ans[bh(i,j)]-b[i][j]));
    84         puts("");
    85     }
    86     return 0;
    87 }
    View Code

    T3

    莫比乌斯反演,咕了

  • 相关阅读:
    卷积神经网络
    降噪自动编码器(Denoising Autoencoder)
    栈式自动编码器(Stacked AutoEncoder)
    限制Boltzmann机(Restricted Boltzmann Machine)
    MATLAB conv2卷积的实现
    二维卷积的基本原理
    范数的物理意义(转)
    卷积的本质及物理意义(全面理解卷积)
    从稀疏表示到低秩表示(五)
    Android官方技术文档翻译——Ant 任务
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11370388.html
Copyright © 2011-2022 走看看