码迷,mamicode.com
首页 > 其他好文 > 详细

JZOJ #4722 跳楼机

时间:2016-08-22 21:22:57      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

给出h、x、y、z,求在h以内,x、y、z可以凑出多少个不同的数。

(1≤h≤10^18,1≤x, y, z≤10^5。)

解题思路:

直接做显然不好做。我们考虑取n个y和m个z,然后再加上x、2 * x、3 * x...,显然地,只要对于每种取法,(ny + mz) % x 的值不同的话,就不会有重复。所以我们先求出 d[i] = c 表示通过选y和z使得和模x等于i的最小和c。然后答案就是 ∑0≤i<x (h - d[i]) / x + 1。至于怎么求d[i],可以发现 d[(i + y) % x] = min d[i] + y、d[(i + z) % x] = d[i] + z,明显的最短路模型。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define i64 long long
 6 using namespace std;
 7 
 8 const int N = 1e5 + 10;
 9 const i64 inf = 1e18 + 1;
10 int x, y, z, inq[N];
11 i64 h, ans, d[N];
12 
13 queue <int> q;
14 
15 void spfa() {
16     for (int i = 0; i < x; i ++) d[i] = inf;
17     d[1] = 1 % x;
18     q.push(1);
19     inq[1] = 1;
20     while (!q.empty()) {
21         int i = q.front(); q.pop();
22         if (d[i] + y < d[(i + y) % x]) {
23             d[(i + y) % x] = d[i] + y;
24             if (!inq[(i + y) % x]) {
25                 inq[(i + y) % x] = 1;
26                 q.push((i + y) % x);
27             }
28         }
29         if (d[i] + z < d[(i + z) % x]) {
30             d[(i + z) % x] = d[i] + z;
31             if (!inq[(i + z) % x]) {
32                 inq[(i + z) % x] = 1;
33                 q.push((i + z) % x);
34             }
35         }
36         inq[i] = 0;
37     }
38 }
39 
40 int main() {
41     scanf("%lld", &h);
42     scanf("%d %d %d", &x, &y, &z);
43     spfa();
44     for (int i = 0; i < x; i ++) if (h > d[i]) ans += (h - d[i]) / x + 1;
45     printf("%lld", ans);
46     return 0;
47 }

 

JZOJ #4722 跳楼机

标签:

原文地址:http://www.cnblogs.com/awner/p/5796948.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!