[POJ] 3539 Elevator

http://poj.org/problem?id=3539

给定一个电梯,可以上升a,b,c层和回到1层,给定楼高h,求可达层数

lyd讲的同余类BFS,方法是先把三个量压成两个,即把h%a,因为对于一个x∈{h%a},若x可达,则x+ak一定可达。

然后考虑在这个模a的剩余系中,b和c的情况。

从1开始连边,从点i连向(i+w)%a,代价为w,其中w为b或c。

意义就是,对于一个楼层x,从x到达最近x+w层的代价为w,这很显然。

从1开始做单源最短路,然后只需要统计dis小于等于h的,大于的显然不可达了。

因为是在模a剩余系下做的,所以对于一个满足dis[u]<=h的u,它是一个剩余系的代表元,要算出剩余系大小。

//drunk,fix later
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

typedef long long ll;

const int MAXN=100005;

struct Edge{
  int next,to;
  ll w;
}e[MAXN<<2];
int ecnt,head[MAXN];
inline void add(int x,int y,ll w){
  e[++ecnt].next = head[x];
  e[ecnt].to = y;
  e[ecnt].w = w;
  head[x] = ecnt;
}

ll h,a,b,c;

queue<int> Q;
int inq[MAXN];
ll dis[MAXN];
void spfa(){
  for(int i=0;i<=a;i++) dis[i]=1ll<<60;
  Q.push(1);inq[1]=1;dis[1]=1;
  while(!Q.empty()){
    int top=Q.front();Q.pop();inq[top]=0;
    for(int i=head[top];i;i=e[i].next){
      int v=e[i].to;
      if(dis[v]>dis[top]+e[i].w){
        dis[v]=dis[top]+e[i].w;
        if(!inq[v]) Q.push(v),inq[v]=1;
      }
    }
  }
}

int main(){
  cin>>h>>a>>b>>c;
  if(a>b) swap(a,b);
  if(a>c) swap(a,c);
  if(a==1) return cout<<h,0;
  for(int i=0;i<a;i++){
    add(i,(i+b)%a,b);
    add(i,(i+c)%a,c);
  }
  ll sum=0;
  spfa();
  for(int i=0;i<a;i++) if(dis[i]<=h) sum+=(ll)(h-dis[i])/a+1;
  cout<<sum;
  return 0;
}

原文地址:https://www.cnblogs.com/ghostcai/p/9281134.html

时间: 2024-10-08 01:09:19

[POJ] 3539 Elevator的相关文章

poj 3539 Elevator——同余类bfs

题目:http://poj.org/problem?id=3539 考虑把层数分为模a剩余系.同类内可通过+若干个a走到. 不同类之间需要通过+b.+c来走到. 需要求出每一类中最小的能走到的.即最短路. 注意memset成0x3f!不要直接memset成1! 仔细一看,long long下赋1是17位,赋0x3f是19位.而h是18位. #include<iostream> #include<cstdio> #include<cstring> #include<

poj 2392 Space Elevator(多重背包+先排序)

Description The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h

POJ 2392 Space Elevator 背包题解

多重背包,本题不需要二分优化.相对简单点.因为重复数十分小,小于10: 而增加一个限制每种材料的高度做法,如果使用逆向填表,那么只需要从这个高度往小递归填表就可以了. 还有就是注意要排序,以限制高度为标准从小到大排序,否则答案错误的. #include <stdio.h> #include <string.h> #include <algorithm> using std::sort; const int MAX_K = 401; const int MAX_H = 4

POJ 2392 Space Elevator(贪心+多重背包)

POJ 2392 Space Elevator(贪心+多重背包) http://poj.org/problem?id=2392 题意: 题意:给定n种积木,每种积木都有一个高度h[i],一个数量num[i],还有一个限制条件,这个积木所在的位置不能高于limit[i],问能叠起的最大高度? 分析: 本题是一道多重背包问题, 不过每个物品的选择不仅仅要受该种物品的数量num[i]限制, 且该物品还受到limit[i]的限制. 这里有一个贪心的结论: 我们每次背包选取物品时都应该优先放置当前limi

poj 2392 Space Elevator (多重背包)

Space Elevator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8110   Accepted: 3843 题目大意  :一群牛要上天  用一些石块堆塔  给出石块的种类  及其每个种类的数量 和该种石块能出现的最高高度  和每种石块的数量 求怎么摆放才能堆得最高 多重背包模板题.... 将所有石块排序  把高度低的放下面 #include<iostream> #include<cstdio>

POJ 2392 Space Elevator(多重背包)

Description The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h

POJ 题目2392 Space Elevator(多重背包)

Space Elevator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9042   Accepted: 4296 Description The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <

poj 2392 Space Elevator DP

该题与poj 1742的思路基本一致:http://www.cnblogs.com/sevenun/p/5442279.html(多重背包) 题意:给你n个电梯,第i个电梯高h[i],数量有c[i]个,但是每个电梯所在高度不能超过a[i]. 求问,怎么样的建造方案能够使电梯能够达到最大高度 思路:首先,必然要使电梯按a[i]进行排序,a[i]最小的电梯先建造.例如,电梯1,只能在高度20以下建造,而电梯2能在高度50以下建造,我当然先建造电梯1,否则如果先建造电梯2,就会导致我建造的高度早早超过

POJ 2392 Space Elevator 贪心+dp

题目链接: http://poj.org/problem?id=2392 题意: 给你k类方块,每类方块ci个,每类方块的高度为hi,现在要报所有的方块叠在一起,每类方块的任何一个部分都不能出现在ai以上的高度,问这些方块能叠的最高高度. 题解: 首先按ai升序排序,尽量让高度限制低的先排掉,如果不这样做一些转移会失效掉: 比如:h1=3,a1=3;h2=4,a2=7 如果先搭1再搭2则合法,但反过来则变成无效的转移了. 处理好顺序之后跑一遍背包就可以了,因为最大高度为40000,比较小,所以用