题解
- 首先,我们知道,如果a可以到达,那么也可以到达
- 那么,一个到达的高度l=ax+by+cz
- 可以先不考虑x,设f[i]为到模x下高度i的可以到达的最小楼层
- 如果我们得到了所有f,答案就是
- 那么如果不考虑x的话,就只有两种转移:
- ①f[(i+y)%x]=f[i]+y
- ②f[(i+z)%x]=f[i]+z
- 也就是一个最短路模型,直接spfa(这题居然不卡spfa)
代码
1 #include <cstdio>
2 #include <cstring>
3 #include <queue>
4 using namespace std;
5 queue<int> Q;
6 struct edge {int to,from,v;}e[200010];
7 long long dis[100010],ans,h;
8 int x,y,z,cnt,visit[100010],head[100010];
9 void insert(int x,int y,int v) { e[++cnt].to=y; e[cnt].from=head[x]; e[cnt].v=v; head[x]=cnt; }
10 void spfa(int s)
11 {
12 memset(dis,-1,sizeof(dis));
13 dis[s]=visit[s]=1; Q.push(s);
14 while (!Q.empty())
15 {
16 int u=Q.front(); Q.pop();
17 visit[u]=0;
18 for (int i=head[u];i;i=e[i].from)
19 if (dis[e[i].to]==-1||dis[e[i].to]>dis[u]+e[i].v)
20 {
21 dis[e[i].to]=dis[u]+e[i].v;
22 if (!visit[e[i].to]) visit[e[i].to]=1,Q.push(e[i].to);
23 }
24 }
25 }
26 int main()
27 {
28 scanf("%lld%d%d%d",&h,&x,&y,&z);
29 for (int i=0;i<x;i++) insert(i,(i+y)%x,y),insert(i,(i+z)%x,z);
30 spfa(1%x);
31 for (int i=0;i<x;i++) if (dis[i]!=-1&&h-dis[i]>=0) ans+=(h-dis[i])/x+1;
32 printf("%lld",ans);
33 }