码迷,mamicode.com
首页 > 其他好文 > 详细

「训练日志18」 (8.16) 认清自己

时间:2019-08-16 22:54:46      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:bfs   and   sed   $1   one   none   ora   water   open   

前几天的题先鸽了

T1 mine

  简单$dp$,注意转移意义即可。

  我的定义比较麻烦,可是参考我关注的其他大佬的博客。

  定义$f_{i,j,k}$表示当前位置$i$,当前元素是$j$,上一个元素是$k$的方案数。i维可以滚起来。

  没啥好说的,稍微麻烦点的就是$?$和$1$了,其他的就模拟转移就可以了。

  小弟不才。

技术图片
  1 #include<cstdio>
  2 #include<string>
  3 #include<iostream>
  4 #include<cstring>
  5 #define LL long long
  6 #define HZOI std
  7 using namespace HZOI;
  8 const int mod=1e9+7;
  9 LL ans;
 10 int n;
 11 char s[1000003],a[1000003];
 12 LL dp[1000003][5][5];
 13 inline void Mod(LL &a) {while (a>=mod) a-=mod;}
 14 int main()
 15 {
 16     char cc=getchar();
 17     while (cc!=0 and cc!=1 and cc!=2 and cc!=* and cc!=?) cc=getchar();
 18     while (cc==0 or cc==1 or cc==2 or cc==* or cc==?) 
 19     {
 20         if (cc==?) a[++n]=4;
 21         else if (cc==*) a[++n]=3;
 22         else a[++n]=cc-48;
 23         cc=getchar();
 24     }
 25     if (a[1]!=4 and a[2]!=4) dp[2][a[2]][a[1]]=1;
 26     if (a[1]==4 and a[2]!=4)
 27     {
 28         if (!a[2])
 29             dp[2][a[2]][0]=1;
 30         if (a[2]==1)
 31             dp[2][a[2]][0]=dp[2][a[2]][3]=1;
 32         if (a[2]==2)
 33             dp[2][a[2]][3]=1;
 34         if (a[2]==3)
 35             dp[2][a[2]][3]=dp[2][a[2]][1]=1;
 36     }
 37     if (a[1]!=4 and a[2]==4)
 38     {
 39         if (!a[1])
 40             dp[2][0][a[1]]=dp[2][1][a[1]]=1;
 41         if (a[1]==1)
 42             dp[2][3][a[1]]=1;
 43         if (a[1]==2) return puts("0"),0;
 44         if (a[1]==3)
 45             dp[2][1][a[1]]=dp[2][2][a[1]]=dp[2][3][a[1]]=1;
 46     }
 47     if (a[1]==4 and a[2]==4)
 48     {
 49         dp[2][0][0]=dp[2][1][0]=dp[2][3][1]=dp[2][1][3]=dp[2][2][3]=dp[2][3][3]=1;
 50     }
 51     for (int i=3; i<=n; ++i)
 52     {
 53         if (!a[i])
 54             for (int j=0; j<3; ++j)
 55             {
 56                 if (!j)
 57                     for (int k=0; k<2; ++k)
 58                         Mod(dp[i][0][j]+=dp[i-1][j][k]);
 59                 if (j==1)
 60                     Mod(dp[i][0][j]+=dp[i-1][j][3]);
 61             }
 62         if (a[i]==1)
 63             for (int j=0; j<4; ++j)
 64             {
 65                 if (!j)
 66                     for (int k=0; k<2; ++k)
 67                         Mod(dp[i][1][j]+=dp[i-1][j][k]);
 68                 if (j==1)
 69                     Mod(dp[i][1][j]+=dp[i-1][j][3]);
 70                 if (j==3)
 71                     for (int k=1; k<4; ++k)
 72                         Mod(dp[i][1][j]+=dp[i-1][j][k]);
 73             }    
 74         if (a[i]==2)
 75             for (int j=1; j<4; ++j)
 76                 Mod(dp[i][2][3]+=dp[i-1][3][j]);
 77         if (a[i]==3)
 78             for (int j=1; j<4; ++j)
 79             {
 80                 if (j==1)
 81                     for (int k=0; k<2; ++k)
 82                         Mod(dp[i][3][j]+=dp[i-1][j][k]);
 83                 if (j==2)
 84                     Mod(dp[i][3][j]+=dp[i-1][j][3]);
 85                 if (j==3)
 86                     for (int k=1; k<4; ++k)
 87                         Mod(dp[i][3][j]+=dp[i-1][j][k]);
 88             }
 89         if (a[i]==4)
 90             for (int g=0; g<4; ++g)
 91             {
 92                 if (!g)
 93                     for (int j=0; j<3; ++j)
 94                     {
 95                         if (!j)
 96                             for (int k=0; k<2; ++k)
 97                                 Mod(dp[i][0][j]+=dp[i-1][j][k]);
 98                         if (j==1)
 99                             Mod(dp[i][0][j]+=dp[i-1][j][3]);
100                     }
101                 if (g==1)
102                     for (int j=0; j<4; ++j)
103                     {
104                         if (!j)
105                             for (int k=0; k<2; ++k)
106                                 Mod(dp[i][1][j]+=dp[i-1][j][k]);
107                         if (j==1)
108                             Mod(dp[i][1][j]+=dp[i-1][j][3]);
109                         if (j==3)
110                             for (int k=1; k<4; ++k)
111                                 Mod(dp[i][1][j]+=dp[i-1][j][k]);
112                     }    
113                 if (g==2)
114                     for (int j=1; j<4; ++j)
115                         Mod(dp[i][2][3]+=dp[i-1][3][j]);
116                 if (g==3)
117                     for (int j=1; j<4; ++j)
118                     {
119                         if (j==1)
120                             for (int k=0; k<2; ++k)
121                                 Mod(dp[i][3][j]+=dp[i-1][j][k]);
122                         if (j==2)
123                             Mod(dp[i][3][j]+=dp[i-1][j][3]);
124                         if (j==3)
125                             for (int k=1; k<4; ++k)
126                                 Mod(dp[i][3][j]+=dp[i-1][j][k]);
127                     }
128             }
129     }
130     Mod(ans+=dp[n][0][0]+dp[n][0][1]+dp[n][1][3]+dp[n][3][1]+dp[n][3][2]+dp[n][3][3]);
131     printf("%lld\n",(ans+mod)%mod);
132 }
mine

 

T2 water

  考试的时候没有深入理解题意,导致蒙到了$20$分。

  其实思路也不难,但是考试的时候真没想到。

  这道题主要是一个思路,要从边界开始向里扫,用边界的状态更新内部状态,找到一个最低的可以流出去的口,这是这道题的关键。

  我们可以考虑$SPFA$遍历整张图,然后不断用dis值更新它的答案,要注意不能之考虑起点的$dis$,也要考虑终点的$a$值,两者取$max$,因为我一定要保证答案不能出现“倒流”的情况。

  小弟不才。

  

技术图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #define LL long long
 4 #define HZOI std
 5 using namespace HZOI;
 6 int n,m;
 7 LL head,tail,a[303][303],dis[303][303],vis[303][303],quei[1000003],quej[1000003];
 8 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
 9 inline void Bfs();
10 inline LL read();
11 inline LL max(LL a,LL b) {return a>b?a:b;}
12 inline LL min(LL a,LL b) {return a<b?a:b;}
13 int main()
14 {
15     n=read(),m=read();
16     for (int i=1; i<=n; ++i)
17         for (int j=1; j<=m; ++j)
18             a[i][j]=read();
19     memset(dis,0x3f,sizeof(dis));
20     head=tail=0;
21     for (int i=1; i<=n; ++i)
22     {
23         dis[i][m]=max(0,a[i][m]);
24         dis[i][1]=max(0,a[i][1]);
25         if (!vis[i][m]) quei[++tail]=i, quej[tail]=m, vis[i][m]=1;
26         if (!vis[i][1]) quei[++tail]=i, quej[tail]=1, vis[i][1]=1;
27     }
28     for (int i=1; i<=m; ++i)
29     {
30         dis[n][i]=max(0,a[n][i]);
31         dis[1][i]=max(0,a[1][i]);
32         if (!vis[n][i]) quei[++tail]=n, quej[tail]=i, vis[n][i]=1;
33         if (!vis[1][i]) quei[++tail]=1, quej[tail]=i, vis[1][i]=1;
34     }
35     Bfs();
36     for (int i=1; i<=n; ++i)
37     {
38         for (int j=1; j<=m; ++j)
39             printf("%lld ",dis[i][j]-a[i][j]);
40         puts("");
41     }
42 }
43 inline void Bfs()
44 {
45     while (head^tail)
46     {
47         int xi=quei[++head],xj=quej[head];
48         vis[xi][xj]=0;
49         for (int i=0; i<4; ++i)
50         {
51             int toi=xi+dx[i],toj=xj+dy[i];
52             if (toi>0 and toi<=n and toj>0 and toj<=m)
53             {
54                 int dtc=max(a[toi][toj],dis[xi][xj]);
55                 if (dis[toi][toj]>dtc)
56                 {
57                     dis[toi][toj]=dtc;
58                     if (!vis[toi][toj]) quei[++tail]=toi,quej[tail]=toj,vis[toi][toj]=1;
59                 }
60             }
61         }
62     }
63 }
64 inline LL read()
65 {
66     LL nn=0,ff=1; char cc=getchar();
67     while (cc<0 or cc>9) {if (cc==-) ff=-1; cc=getchar();}
68     while (cc>=0 and cc<=9) nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
69     return nn*ff;
70 }
water

 

「训练日志18」 (8.16) 认清自己

标签:bfs   and   sed   $1   one   none   ora   water   open   

原文地址:https://www.cnblogs.com/LH-Xuanluo/p/11366524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!