NOIPTGT2 vijosP1002 过河

过河
(river.pas/c/cpp)

【问题描述】

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。
  题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

【输入文件】输入文件river.in的第一行有一个正整数L(1 <= L <= 10^9),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1 <= S <= T <= 10,1 <= M <= 100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。

【输出文件】

输出文件river.out只包括一个整数,表示青蛙过河最少需要踩到的石子数。
【样例输入】
10
2 3 5
2 3 5 6 7

【样例输出】
2

【数据规模】对于30%的数据,L <= 10000;
对于全部的数据,L <= 10^9。

好久之前写的,直接AC。

状态转移方程不难推,主要是状态压缩,因为长度L有1E,但石子只有100个,所以石子的分布是比较稀疏的,我直接把距离大于100的压缩到100以内。因为当距离足够长时可以跳到下一个石子前的任意位置(差不多)。但要注意S=T时不能这样压缩,额外处理一下就行了。我的小包同学一直弄不明白这个RA好多次。

因为我懒得想所以直接设为100.准确的是“只要求出1--10里面任意两个数的最小公倍数,然后取最大的,可以证明当两石块之间的距离大于它的时候,那么大于它的部分的每一个点都可以通过这两个数的某一种组合跳到,所以当两个石块间的距离大于这个最小公倍数,那么就把它们的距离缩小到这个最小公倍数.
路径压缩后,就可以DP求出最小踩石子个数。设f[i]表示到达第i个位置最小踩多少个石子.
则f[i]=min(f[i-j]+d[i])(1<=i<=l+t)(s<=j<=t),d[i]表示第i个位置是否有石子.
最后的答案就是在l to l+t 之间找最小。”——摘自http://blog.sina.com.cn/s/blog_5ef211b10100ch5z.html

var
 a:array[0..101] of longint;
 y:array[0..10000] of boolean;
 f:array[0..10000] of longint;
 i,j,n,m,ans,l,s,t,x:longint;

procedure qs(l,r:longint);
var
 i,j,x,t:longint;
begin
 i:=l;j:=r;x:=a[(l+r) div 2];
 while i<j do begin
  while a[i]<x do inc(i);
  while a[j]>x do dec(j);
  if i<=j then begin
   t:=a[i];a[i]:=a[j];a[j]:=t;
   inc(i);dec(j);
  end;
 end;
 if i<r then qs(i,r);
 if l<j then qs(l,j);
end;

begin
 readln(l);readln(s,t,m);
 for i:=1 to m do read(a[i]);
 a[m+1]:=l;
 qs(1,m);
 if s=t then begin
  for i:=1 to m do if a[i] mod s=0 then inc(ans);
  writeln(ans);
 end

 else begin
  for i:=1 to m+1 do if a[i]-a[i-1]>100 then begin
    x:=a[i]-a[i-1]-100;
    for j:=i to m+1 do a[j]:=a[j]-x;
   end;

   for i:=1 to m do y[a[i]]:=true;
   l:=a[m+1];
   for i:=1 to l do f[i]:=1000;
   for i:=1 to l do
    for j:=s to t do
     if i-j>=0 then
      if y[i] then begin
       if f[i-j]+1<f[i] then f[i]:=f[i-j]+1;
      end else if f[i-j]<f[i] then f[i]:=f[i-j];
      writeln(f[l]);
  end;
end.
时间: 2024-09-14 04:30:38

NOIPTGT2 vijosP1002 过河的相关文章

洛谷 【P1052】过河

P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度).坐标为0的点表示桥的起点,坐标为L的点表示桥的终点.青蛙从桥的起点开始,不停的向终点方向跳跃.一次跳跃的距离是S到T之间的任意正整数(包括S,T).当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥. 题目给出独木桥的长度

贪心—— P1809 过河问题_NOI导刊2011提高(01)

洛谷——P1809 过河问题_NOI导刊2011提高(01) 题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较长的人所用时间. 现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河. 注意,只有船在东岸(西岸)的人才能坐上船划到对岸. 输入输出格式 输入格式: 输入文件第一行为人数N,以下有N行

马拦过河卒心得体会

题目棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒". 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 输入一行四个数据,分别表示B点坐标和马的坐标.(保证所有的数据有解) 输出一个数据

NOIP2005 过河

描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度).坐标为0的点表示桥的起点,坐标为L的点表示桥的终点.青蛙从桥的起点开始,不停的向终点方向跳跃.一次跳跃的距离是S到T之间的任意正整数(包括S,T).当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥. 题目给出独木桥的长度L,青蛙跳跃的距离范围

hdu 4842(NOIP 2005 过河)之 动态规划(距离压缩)

/* hdu 4842(NOIP 2005 过河)之 动态规划(距离压缩) dp[i] := 到桥上的i位置,最少需要踩到的石子数. dp[i] = min(dp[i], dp[i-j] + isStone[i])    条件: (1) S<=j<=T (2) dp[i-j]是青蛙可以到达的点 独木桥长度L,最大为10^9,直接用转移方程,TLE:由于桥上的石子个数100,所以当石子分布在独木桥上时,是很稀疏的. (1)S!=T 考虑,对于此题关键在于求踩到的石子数,而非跳的次数,对于两个相邻

商人过河问题(DFS)

问题描述:3个商人带着3个仆人过河,过河的工具只有一艘小船,只能同时载两个人过河,包括划船的人.在河的任何一边,只要仆人的数量超过商人的数量,仆人就会联合起来将商人杀死并抢夺其财物,问商人应如何设计过河顺序才能让所有人都安全地过到河的另一边. 详细过程参见<数学模型>第四版(姜启源) #include <cstdio> #define maxn 101 int num;//number of bus or fol int graph[maxn*maxn][maxn*maxn]; i

【水】noip2002普及 过河卒

这题似乎是当年的马拦过河卒,好久的回忆啊... 过河卒 来源 NOIP2002普及组 题目描述 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例 如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C).卒不能通过对方马的控制点. 棋盘用坐标表示,A 点(0,0).B 点(n,m)(n,m 为不超过 25 的整数,并由键盘输入),同样马的

Vijos P1002 过河 (NOIP提高组2005)

链接:https://www.vijos.org/p/1002 解析: 若 p*x+(p+1)*y=Q(采用跳跃距离p和p+1时可以跳至任何位置Q),则在Q ≥ P*(P-1)时是一定有解的. 由于题目给出的一个区间是1≤S≤T≤10,于是当相邻的两个石子之间的距离不小于8*9=72时,则后面的距离都可以到达,我们就可以认为它们之间的距离就是72.如此一来,我们就将原题L的范围缩小为了100*72=7200,动态规划算法完全可以承受了. 但是当S=T时,上述等式是无法使用的,在这种情况下,只需要

P1244 青蛙过河

P1244 青蛙过河 题目描述 有一条河,左边一个石墩(A区)上有编号为1,2,3,4,-,n的n只青蛙,河中有k个荷叶(C区),还有h个石墩(D区),右边有一个石墩(B区),如下图所示.n只青蛙要过河(从左岸石墩A到右岸石墩B),规则为: (1)石墩上可以承受任意多只青蛙,荷叶只能承受一只青蛙(不论大小): (2)青蛙可以:A→B(表示可以从A跳到B,下同),A→C,A→D,C→B,D→B,D→C,C→D: (3)当一个石墩上有多只青蛙时,则上面的青蛙只能跳到比它大1号的青蛙上面. 你的任务是