题目大意

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

思路

  本题动规不用说,问题在于怎么使路径压缩。

思路1

  求出一个单位长度$x$,使得青蛙在区间$[1,x]$上从$[1,T]$开始起跳时,总会有一种跳法跳到$x$处。更严谨地说,也就是存在一个序列$K$,使得$x=\sum_{i=S}^T iK_i$。我们看看$S,T$取值范围,简单粗暴地想,令$K_i=\gcd(1,2,\cdots i-1, i+1, \cdots 10)$即可。也就是说,$x=\mathrm{lcm}(1, 2, \cdots, 10)$。所以对每一个间隔模个$x$即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_LEN = 2100 * 100, MAX_STONE_CNT = 110, Unit = 2050, INF = 0x3f3f3f3f;
int Delta[MAX_STONE_CNT], F[MAX_LEN], A[MAX_STONE_CNT];
bool HaveStone[MAX_LEN];
int Len, S, T, TotStone; int main()
{
scanf("%d%d%d%d", &Len, &S, &T, &TotStone);
for (int i = 1; i <= TotStone; i++)
scanf("%d", A + i);
sort(A + 1, A + TotStone + 1);
if (S == T)
{
int ans = 0;
for (int i = 1; i <= TotStone; i++)
ans += (A[i] % T == 0);
printf("%d\n", ans);
return 0;
}
for (int i = 1; i <= TotStone; i++)
{
Delta[i] = A[i] - A[i - 1];
}
Delta[TotStone + 1] = Len - A[TotStone];
for (int i = 1; i <= TotStone + 1; i++)
Delta[i] %= Unit;
int prevP = 0;
for (int i = 1; i <= TotStone; i++)
HaveStone[prevP += Delta[i]] = true;
Len = prevP + Delta[TotStone + 1];
memset(F, INF, sizeof(F));
F[0] = 0;
for (int i = 1; i <= Len; i++)
for (int j = S; j <= T && j <= i; j++)
F[i] = min(F[i], F[i - j] + HaveStone[i]);
int ans = INF;
for (int i = Len - T; i <= Len; i++)
ans = min(ans, F[i]);
printf("%d\n", ans);
return 0;
}

思路二

  求一个区间长度,使得任何大于这个区间长度的位置都可以到达。我们做过《小凯的疑惑》,知道对任意两个互质的数$a,b$,若整数$x>ab$,则总存在整数$k,t$,使得$x=ka+tb$。因为$t, t-1$互质,所以任何大于$t(t-1)$的位置都可到达。所以遇到大于$t(t-1)$的间隔便将其改为$t(t-1)$即可达到压缩效果。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_LEN = 2100 * 100, MAX_STONE_CNT = 110, INF = 0x3f3f3f3f;
int A[MAX_STONE_CNT], Delta[MAX_STONE_CNT], F[MAX_LEN];
bool HaveStone[MAX_LEN];
int Len, S, T, TotStone, Unit; int main()
{
scanf("%d%d%d%d", &Len, &S, &T, &TotStone);
Unit = T * (T - 1);
for (int i = 1; i <= TotStone; i++)
scanf("%d", A + i);
sort(A + 1, A + TotStone + 1);
if (S == T)
{
int ans = 0;
for (int i = 1; i <= TotStone; i++)
ans += (A[i] % T == 0);
printf("%d\n", ans);
return 0;
}
for (int i = 1; i <= TotStone; i++)
{
Delta[i] = A[i] - A[i - 1];
}
Delta[TotStone + 1] = Len - A[TotStone];
for (int i = 1; i <= TotStone + 1; i++)
if (Delta[i] > Unit)
Delta[i] = Unit;
int prevP = 0;
for (int i = 1; i <= TotStone; i++)
HaveStone[prevP += Delta[i]] = true;
Len = prevP + Delta[TotStone + 1];
memset(F, INF, sizeof(F));
F[0] = 0;
for (int i = 1; i <= Len; i++)
for (int j = S; j <= T && j <= i; j++)
F[i] = min(F[i], F[i - j] + HaveStone[i]);
int ans = INF;
for (int i = Len - T; i <= Len; i++)
ans = min(ans, F[i]);
printf("%d\n", ans);
return 0;
}

  

luogu1052 过河的更多相关文章

  1. [LeetCode] Frog Jump 青蛙过河

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  2. [codevs1105][COJ0183][NOIP2005]过河

    [codevs1105][COJ0183][NOIP2005]过河 试题描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青 ...

  3. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  4. 袋鼠过河---DP

    题目:一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远,每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5, ...

  5. NOIP2005过河[DP 状态压缩]

    题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...

  6. ACM 过河问题

    过河问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的 ...

  7. NOIP 2005 青蛙过河

    做题记录:2016-08-10 21:58:09 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都 ...

  8. 过河问题nyoj47

    时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的是 ...

  9. 商人过河问题(DFS)

    问题描述:3个商人带着3个仆人过河,过河的工具只有一艘小船,只能同时载两个人过河,包括划船的人.在河的任何一边,只要仆人的数量超过商人的数量,仆人就会联合起来将商人杀死并抢夺其财物,问商人应如何设计过 ...

随机推荐

  1. ajax不执行success的问题

    有时候经常会遇到ajax请求后台,然后后台返回数据后,不触发ajax的success函数的问题,归根到底,这与ajax的参数设置dataType和后台的返回值的类型有关,现总结如下: 一.后台返回值的 ...

  2. Resetting the SMC & PRAM

    Resetting the SMC & PRAM on portables with a battery you should not remove on your own 1. Shut d ...

  3. 微信小程序——weui的使用

    使用在根目录中复制weui.wxss,app.wxss中引入 在weui.io中查看到自己想要的样式表后,到第二个网站复制代码,复制到自己的项目中即可 <!--pages/register/re ...

  4. C# MVC ajax上传 文件

    用普通的ajax提交表单的时候,不能把文件流传到后端去,所以要用到jquery.form.js jquery.form.js到官网下载或者从这里下载:http://pan.baidu.com/s/1c ...

  5. CVPR2016 Paper list

    CVPR2016 Paper list ORAL SESSIONImage Captioning and Question Answering Monday, June 27th, 9:00AM - ...

  6. Python ---- KMP(博文推荐+代码)

    既解决完后宫问题(八皇后问题)后,又利用半天的时间完成了著名的“看毛片”算法——KMP.对于初学者来说这绝对是个大坑,非常难以理解. 在此,向提出KMP算法的三位大佬表示诚挚的敬意.!!!牛X!!! ...

  7. How To : Modify ASM SYS password using asmcmd 11g R2 and upper

    修改RAC 11gR2及以上版本的ASM的SYS的密码方法 [grid]$ asmcmd ASMCMD> orapwusr --modify --password sys Enter passw ...

  8. win10 Ubuntu子系统安装&odoo10社区版安装

    参考文档: http://www.cnblogs.com/odoouse/p/5995603.html https://www.jianshu.com/p/58090215bda8 一.win10 U ...

  9. vue轮播插件vue-awesome-swiper

    https://surmon-china.github.io/vue-awesome-swiper/ 第一步安装 npm install vue-awesome-swiper --save 第二部在m ...

  10. textarea 提交到数据库的内容,输出到 html 中显示正常的格式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...