【挖坑记】JZOJ 4722 跳楼机
2016-08-22 12:39
246 查看
题目大意
一幢大楼高为h,有四种操作,前三种分别是上升x、y、z层楼,最后一个是回到一楼。h<=1e15,x,y,y<=1e5
时间限制1s
空间限制256M
解题思路
首先有一个数组d[i]=c,表示在c mod z=i的情况下,只用前两种操作可以达到的最小高度,然后ans=∑z−1i=0trunc((h−d[i])/z)+1。而d数组的求解可以用最短路
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 100006 #define fr(i,a,b) for(i=a;i<=b;i++) using namespace std; typedef long long ll; const ll ding=100002; int i,x,y,z,f[maxn]; ll n,ans,dis[maxn]; bool kan[maxn]; void spfa() { int u,i=0,j=1; f[1]=1; dis[1]=1; kan[1]=1; while (i!=j) { i=i%ding+1; u=f[i]; if (dis[(u+y)%z]>dis[u]+y) { dis[(u+y)%z]=dis[u]+y; if (!kan[(u+y)%z]) { j=j%ding+1; f[j]=(u+y)%z; kan[(u+y)%z]=1; } } if (dis[(u+x)%z]>dis[u]+x) { dis[(u+x)%z]=dis[u]+x; if (!kan[(u+x)%z]) { j=j%ding+1; f[j]=(u+x)%z; kan[(u+x)%z]=1; } } kan[u]=0; } return; } int main() { scanf("%lld",&n); scanf("%d%d%d",&x,&y,&z); memset(dis,63,sizeof(dis)); spfa(); fr(i,0,z-1) if (dis[i]<=n) ans+=(n-dis[i])/z+1; printf("%lld\n",ans); return 0; }
相关文章推荐
- JZOJ4722 跳楼机 巧妙地转换为最短路模型
- Jzoj4722 跳楼机
- 【挖坑记】JZOJ 4707 艾比索特
- 【挖坑记】JZOJ 4714 公约数
- 【挖坑记】JZOJ 4729 道路修建
- 【挖坑记】JZOJ 4735 最小圈
- 【挖坑记】 JZOJ 4724 斐波那契
- 【挖坑记】JZOJ 4715
- 【挖坑记】JZOJ 4721 最长公共子序列
- 【挖坑记】JZOJ 4738 神在夏至祭降下了神谕
- 【挖坑记】JZOJ 4727 挺进
- 【挖坑记】JZOJ 4726 种花
- 【挖坑记】JZOJ 4711 Binary
- 【挖坑记】JZOJ 4706
- JZOJ 4366. 【GDKOI2016】项链
- 【JZOJ 3976】【NOI2015模拟1.17】⑨
- [JZOJ5523] +/-
- jzoj 2746.【2012中山市选】选数排列(pick) 二分答案+dp
- jzoj3588 【中山市选2014】J语言 (表达式解析)
- jzoj 3587. 【中山市选2014】dwarf tower 暴力水题