[关闭]
@ysner 2018-04-04T14:08:36.000000Z 字数 1364 阅读 1913

Luogu3403跳楼机

最短路


题面

给你三个数,,,问你能够凑出多少个[1,]之间的数。

解析

处理出,能凑出的高度
然后这些高度凑一些就可以得到其它的高度
那么可以把这些,凑出的高度对取模,其它的用来填补
所以设表示,凑出高度%需要的最低高度
那么答案就是

代码

  1. #include<iostream>
  2. #include<cmath>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<algorithm>
  7. #include<queue>
  8. #define ll long long
  9. #define re register
  10. #define il inline
  11. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  12. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  13. using namespace std;
  14. const int N=5e5;
  15. int h[N],cnt,X,Y,Z;ll dp[N];
  16. bool vis[N];
  17. ll ans,H;
  18. struct Edge{int to,next,w;}e[N<<1];
  19. struct node
  20. {
  21. ll dis;int u;
  22. bool operator < (const node &o) const {return dis>o.dis;}
  23. };
  24. priority_queue<node>Q;
  25. il void add(re int u,re int v,re int w){e[++cnt]=(Edge){v,h[u],w};h[u]=cnt;}
  26. il ll gi()
  27. {
  28. re ll x=0,t=1;
  29. re char ch=getchar();
  30. while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  31. if(ch=='-') t=-1,ch=getchar();
  32. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  33. return x*t;
  34. }
  35. il void Dijstra()
  36. {
  37. memset(dp,127,sizeof(dp));dp[1%X]=1;Q.push((node){1,1%X});
  38. while(!Q.empty())
  39. {
  40. re int u=Q.top().u;Q.pop();
  41. if(vis[u]) continue;vis[u]=1;
  42. for(re int i=h[u];i+1;i=e[i].next)
  43. {
  44. re int v=e[i].to;
  45. if(dp[v]>dp[u]+e[i].w)
  46. {
  47. dp[v]=dp[u]+e[i].w;
  48. Q.push((node){dp[v],v});
  49. }
  50. }
  51. }
  52. }
  53. int main()
  54. {
  55. memset(h,-1,sizeof(h));
  56. H=gi();X=gi();Y=gi();Z=gi();
  57. if(Y<X) swap(Y,X);if(Z<X) swap(Z,X);
  58. fp(i,0,X-1) add(i,(i+Y)%X,Y),add(i,(i+Z)%X,Z);
  59. Dijstra();
  60. fp(i,0,X-1) if(dp[i]<=H) ans+=((H-dp[i])/X+1);
  61. printf("%lld\n",ans);
  62. return 0;
  63. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注