描述

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

题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

对于30%的数据,L <= 10000;

对于全部的数据,L <= 10^9。

格式

输入格式

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

输出格式

输出只包括一个整数,表示青蛙过河最少需要踩到的石子数。

样例1

样例输入1[复制]

10

2 3 5

2 3 5 6 7

样例输出1[复制]

2

限制

1s

来源

NOIp2005 第二题

【题解】



很容易想到方程

f[i] =min(f[i-t..i-s]) + 1;(i处有石头)

f[i] =min(f[i-t..i-s]);(i处没有石头)

但是n很大。不能直接写;

需要优化;

->m很小只有100;

则如果n到了极限数据1e9;

那么相邻的石头之间,或者石头和起点和终点直接的距离可能会非常大。

则可以在这里做文章->每次走一大段没石头的长度;

这个长度应该是多少呢?

有这样一个方程

x*p+y*(p+1) = Q

当Q大于等于p*(p-1)的时候;

该方程恒有解;

例如

4 5

则 12,13,14…都可以通过这两种步数得到

即12之后连续的数字都能通过4和5累加得到;

找到了证明:

    •由于p与p+1间隔1,故方程px+(p+1)y=Q有整数解,设其解为
• x=x0+(p+1)t,y=y0-pt(t是整数)
•取适当的t,使得0≤x≤p(只需在x0上加上或减去若干个p+1),则当Q>p(p-1)-1时,有
•(p+1)y=Q-px>p(p-1)-1-px≥p(p-1)-1-p*p=-(p+1)
•于是y>-1,故y≥0也是非负整数。证毕.

则如果我们发现两个相邻的石头之间的距离大于s*(s-1)+t则直接让其变成s*(s-1)+t就好.

例子:

石头x 1 2 3…1000 1001 1002 石头y

石头y之后的状态往前找前一个状态的时候最多就是1002-t;

不会在往前了;

则如果s*(s-1) +t< 1002

则从s*(s-1)开始的数字都能连续取到了;然后再加上t用来替代原来石头y之后的状态的转移;

这样就变成

石头x 1 2 3.. s*(s-1)+t-t,s*(s-1)+t-(t-1)…s*(s-1)+t 石头y;

石头y以及后面的状态都能够从

s*(s-1)+t-t,s*(s-1)+t-(t-1)…s*(s-1)+t这一段得到转移;

所以不会影响原来的解;

多想想吧。

再换个思路理解下:



从石头x左边t处的石头转移到x处,之后,因为石头x和y之间没有任何石头了。所以这个状态不会变化。而经过s*(s-1)之后就能够把状态传递到y-t了。上面那个方程保证了我们一定能够把x的状态通过有限次的s和s+1这两种步数传递到s*(s-1)(因为我们把这个x和y之间的距离变成了s*(s-1)+t)

然后同理

x+1-t的状态会传递到x+1的位置。然后经过s*(s-1)也能传递到s*(s-1)+1.则y后面的状态也能通过减t得到这个状态。

依次类推。。

重要的在于这些状态在这两个石头之间不会再发生变化了。只是单纯地传递.

#include <cstdio>
#include <algorithm> using namespace std; const int MAXM = 150;
const int INF = 2100000; int l, s, t, m;
int pos[MAXM];
int f[10000];
int should[MAXM]; int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d", &l);
scanf("%d%d%d", &s, &t, &m);
for (int i = 1; i <= m; i++)
scanf("%d", &pos[i]);
sort(pos + 1, pos + 1 + m);
if (s == t)
{
int ans = 0;
for (int i = 1; i <= m; i++)
if (!(pos[i] % s))
ans++;
printf("%d\n", ans);
}
else
{
int MOD = s*(s - 1) + t;
for (int i = 1; i <= m; i++)
{
should[i] = pos[i] - pos[i - 1];
if (should[i] > MOD)
should[i] = MOD;
}
int temp1 = l - pos[m];
if (temp1 > MOD)
temp1 = MOD;
for (int i = 1; i <= m; i++)
pos[i] = pos[i - 1] + should[i];
int maxl = pos[m] + temp1;
for (int i = 1; i <= m; i++)
f[pos[i]] = 1;
for (int i = 1; i <= maxl; i++)
{
int mi = INF;
for (int j = s; j <= t; j++)
if (i - j >= 0)
mi = min(mi, f[i - j]);
f[i] += mi;
}
int ans = f[maxl];
for (int i = maxl + 1; i <= maxl + t; i++)
{
int mi = INF;
for (int j = s; j <= t; j++)
if ((i - j >= 0) && (i - j) < maxl)
mi = min(mi, f[i - j]);
if (ans > mi)
ans = mi;
}
printf("%d\n", ans);
}
return 0;
}

【33.00%】【vijos P1002】过河的更多相关文章

  1. Vijos p1002 过河 离散化距离+区间DP

    链接:https://vijos.org/p/1002 题意:一条长度为L(L <= 1e9)的桥上有N(1<= N <= 100)颗石头.桥的起点为0终点为L.一只青蛙从0开始跳, ...

  2. Vijos P1002 过河 (NOIP提高组2005)

    链接:https://www.vijos.org/p/1002 解析: 若 p*x+(p+1)*y=Q(採用跳跃距离p和p+1时能够跳至不论什么位置Q),则在Q ≥ P*(P-1)时是一定有解的. 因 ...

  3. 洛谷 P1002过河卒

    洛谷 P1002过河卒 题目描述 棋盘上AA点有一个过河卒,需要走到目标BB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点 ...

  4. 洛谷P1002 过河卒 [2017年4月计划 动态规划15]

    P1002 过河卒 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之 ...

  5. P1002 过河卒【dp】

    P1002 过河卒 题目描述 棋盘上AAA点有一个过河卒,需要走到目标BBB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CCC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制 ...

  6. Vijos 1002 过河

    这是我写的在Vijos上的第一题.这道题在我刚学完DP的时候,就做过.当时年少轻狂,没有看数据的范围,直接暴力DP,结果TLE....后来就没有再碰过.知道最近觉得快要省赛了,有必要把原来没有做出来的 ...

  7. 洛谷 P1002 过河卒 【棋盘dp】

    题目链接:https://www.luogu.org/problemnew/show/P1002 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点 ...

  8. 洛谷[P1002]过河卒

    原题地址:https://www.luogu.org/problemnew/show/P1002 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点 ...

  9. 洛谷P1002 过河卒 题解 动态规划

    题目链接:https://www.luogu.com.cn/problem/P1002 题目大意 棋盘上\(A\)点有一个过河卒,需要走到目标\(B\)点.卒行走的规则:可以向下.或者向右.同时在棋盘 ...

随机推荐

  1. Centos 6 vnc 部署

    一.安装gnome桌面环境 yum groupinstall -y 'X Window System' yum groupinstall -y "Desktop" 二.部署vnc ...

  2. 5、list列表常用方法说明

    创建列表: 1 2 3 name_list = ['alex', 'seven', 'eric'] 或 name_list = list(['alex', 'seven', 'eric']) 基本操作 ...

  3. Unity自带网络功能——NetworkView组件、Serialize、RPC

    Unity拥有大量的第三方插件,专门提供了对网络功能的支持.可是,大部分开发人员第一次接触到的还是Unity自带的网络功能,也就是大家常常说到的Unity Networking API.这些API是借 ...

  4. 损失函数 - Andrew Ng机器学习公开课笔记1.2

    线性回归中提到最小二乘损失函数及其相关知识.对于这一部分知识不清楚的同学能够參考上一篇文章<线性回归.梯度下降>. 本篇文章主要解说使用最小二乘法法构建损失函数和最小化损失函数的方法. 最 ...

  5. php实现兼容Unicode文字的字符串大写和小写转换strtolower()和strtoupper()

    前言 网上流传着这么一个腾讯笔试题: PHP的strtolower()和strtoupper()函数在安装非中文系统的server下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode ...

  6. Docker搭建ES

    Centos7安装ES 和 Docker搭建ES 文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.linux centos7.x安装ES ...

  7. 23种设计模式——Prototype模式

    Prototype模式是提供自我复制的功能.包括浅拷贝和深拷贝. 一.Prototype模式的用途 场景1:游戏场景中有很多类似的敌人,它们的技能都一样,但是随着敌人出现的位置和不同,它们的能力也不太 ...

  8. [TypeStyle] Load raw CSS in TypeStyle

    TypeStyle tries to be an all in one CSS in JS management solution so you can always fall back to raw ...

  9. Kinect for Xbox one(v2) + Ubuntu 14.04 +ROS 安装

    相比于kinect for xbox 360(v1)通过结构光来获取深度,Kinect for Xbox one(v2) 采用time flight技术,极大改善了深度图像的性能. kinect fo ...

  10. PWA之消息推送——Notification

    原文 简书原文:https://www.jianshu.com/p/69042b92cae1 大纲 1.推送通知的概念 2.消息推送的知识点 3.实例 1.推送通知的概念 大部分现代 Web 应用都需 ...