luogu1052 过河
题目大意
在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点: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 过河的更多相关文章
- [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 ...
- [codevs1105][COJ0183][NOIP2005]过河
[codevs1105][COJ0183][NOIP2005]过河 试题描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青 ...
- A*算法 -- 八数码问题和传教士过河问题的代码实现
前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...
- 袋鼠过河---DP
题目:一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远,每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5, ...
- NOIP2005过河[DP 状态压缩]
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- ACM 过河问题
过河问题 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的 ...
- NOIP 2005 青蛙过河
做题记录:2016-08-10 21:58:09 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都 ...
- 过河问题nyoj47
时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的是 ...
- 商人过河问题(DFS)
问题描述:3个商人带着3个仆人过河,过河的工具只有一艘小船,只能同时载两个人过河,包括划船的人.在河的任何一边,只要仆人的数量超过商人的数量,仆人就会联合起来将商人杀死并抢夺其财物,问商人应如何设计过 ...
随机推荐
- MySQL 执行计划中Extra的浅薄理解
1.using where: Extra中出现“Using where”,通常来说,意味着全表扫描或者在查找使用索引的情况下,但是还有查询条件不在索引字段当中. 如果需要回表也是用这个. 2.usin ...
- JS——事件的绑定与解绑
1.绑定形式 ele.addEventListener(evtName, fn) ele["on" + evtName] = function () {} ele.onclick ...
- Please, commit your changes or stash them before you can merge
参照 : https://blog.csdn.net/iefreer/article/details/7679631 用git pull来更新代码的时候,遇到了下面的问题: error: Your l ...
- strcmp 与 _tcscmp
strcmp 用来比较ANSI字符串,而_tcscmp用来比较UNICODE(宽字符)的字符串.ANSI字符串中,1个英文字母为1个字节,1个中文字符为2个字节,遇到0字符表示字符串结束.而在UNIC ...
- Eclipse 使用前的配置
一,修改eclipse对jdk的依赖项 1.查看设置的编译器编译版本:设置成本地jdk一致的版本 点击窗口->首选项 找到java 选择编辑器,查看现在的编译jdk版本 改成本地jdk版本 jd ...
- HDU 2414 Chessboard Dance(模拟题,仅此纪念我的堕落)
题目 模拟题也各种wa,我最近真的堕落了,,,,,智商越来越为负数了!!!!!!!! #include<stdio.h> #include<string.h> #include ...
- isset在php5.6-和php7.0+的一些差异
今天在公司实现一个模块功能时写了如下代码: class ProductCategory { const TYPES = [ 1 => 'type1', 2 => 'type2', ]; p ...
- Python - 模块(一)
目录 Python - 模块(一) 模块的引用方式 常用模块 random(随机模块) os模块 sys 序列化模块 hashlib subprocess optparse struct Python ...
- Linux - centos7 下 MySQL(mariadb) 和 主从复制
目录 Linux - centos7 下 MySQL(mariadb) 和 主从复制 MySQL(mariadb) 安装MySQL(mariadb) 配置数据库的中文支持 在远程用 mysql客户端去 ...
- JVM内存监控(五)
频繁fullgc排查 jvm配置 -Xms200m -Xmx200m -Xmn50m -XX:PermSize=30m -XX:+HeapDumpBeforeFullGC -XX:+HeapDumpA ...