JZOJ 4722. 跳楼机
Posted traveller-ly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZOJ 4722. 跳楼机相关的知识,希望对你有一定的参考价值。
做法:先考虑Hash,发现行不通,然后思考,处理出f[i]数组表示在不使用x的情况下达到的高度%x意义下等于i的最低高度。
View Code
那么如果到达了这个高度,就可以在这个基础上不断的跳x,达到i+kx的高度,这种高度对答案的贡献就是(h-f[i])/x+1。考虑
如何计算f,有两个明显的转移f[(i+y)%x] = f[i] + y, 对于z同理,于是这道题就被转变成最短路的模型,利用spfa求F[i]即可
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <queue> 5 #define LL long long 6 #define N 100007 7 using namespace std; 8 LL h,f[N],ans; 9 int x,y,z,tot,ls[N]; 10 struct edge{ 11 int to,next,w; 12 }e[N*4]; 13 queue<int> q; 14 bool v[N]; 15 16 void Add(int u,int v,int w){ 17 e[++tot].to=v; 18 e[tot].w=w; 19 e[tot].next=ls[u]; 20 ls[u]=tot; 21 } 22 23 void Spfa(){ 24 memset(f,0x3f3f3f3f,sizeof(f)); 25 f[1%x]=1; v[1%x]=1; q.push(1%x); 26 for(;!q.empty();){ 27 int now=q.front(); q.pop(); 28 for(int i=ls[now];i;i=e[i].next){ 29 int vis=e[i].to; 30 if(f[now]+e[i].w>=f[vis]) continue; 31 f[vis]=f[now]+e[i].w; 32 if(!v[vis]){ 33 v[vis]=1; 34 q.push(vis); 35 } 36 } 37 v[now]=0; 38 } 39 } 40 41 int main(){ 42 scanf("%lld", &h); 43 scanf("%d%d%d",&x,&y,&z); 44 for(int i=0;i<x;i++) Add(i,(i+y)%x,y),Add(i,(i+z)%x,z); 45 Spfa(); 46 for(int i=0;i<x;i++) if(f[i]<=h) ans+=(h-f[i])/(LL)x+1; 47 printf("%lld", ans); 48 }
以上是关于JZOJ 4722. 跳楼机的主要内容,如果未能解决你的问题,请参考以下文章