@ysner
2018-04-04T06:08:36.000000Z
字数 1364
阅读 2473
最短路
给你三个数,,,问你能够凑出多少个[1,]之间的数。
处理出,能凑出的高度
然后这些高度凑一些就可以得到其它的高度
那么可以把这些,凑出的高度对取模,其它的用来填补
所以设表示,凑出高度%为需要的最低高度
那么答案就是
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<cstdlib>#include<algorithm>#include<queue>#define ll long long#define re register#define il inline#define fp(i,a,b) for(re int i=a;i<=b;i++)#define fq(i,a,b) for(re int i=a;i>=b;i--)using namespace std;const int N=5e5;int h[N],cnt,X,Y,Z;ll dp[N];bool vis[N];ll ans,H;struct Edge{int to,next,w;}e[N<<1];struct node{ll dis;int u;bool operator < (const node &o) const {return dis>o.dis;}};priority_queue<node>Q;il void add(re int u,re int v,re int w){e[++cnt]=(Edge){v,h[u],w};h[u]=cnt;}il ll gi(){re ll x=0,t=1;re char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;}il void Dijstra(){memset(dp,127,sizeof(dp));dp[1%X]=1;Q.push((node){1,1%X});while(!Q.empty()){re int u=Q.top().u;Q.pop();if(vis[u]) continue;vis[u]=1;for(re int i=h[u];i+1;i=e[i].next){re int v=e[i].to;if(dp[v]>dp[u]+e[i].w){dp[v]=dp[u]+e[i].w;Q.push((node){dp[v],v});}}}}int main(){memset(h,-1,sizeof(h));H=gi();X=gi();Y=gi();Z=gi();if(Y<X) swap(Y,X);if(Z<X) swap(Z,X);fp(i,0,X-1) add(i,(i+Y)%X,Y),add(i,(i+Z)%X,Z);Dijstra();fp(i,0,X-1) if(dp[i]<=H) ans+=((H-dp[i])/X+1);printf("%lld\n",ans);return 0;}
