描述

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点: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. (转)ORA-00257归档日志写满的解决方法

    转自:http://www.cnblogs.com/xwdreamer/p/3804509.html 背景: 在前一篇博客中我们提到了如何启动或关闭oracle的归档(ARCHIVELOG)模式,在我 ...

  2. HttpWatch--time chart分析

    这是一个IE的插件,下载可以点这里.下载后解压如下图所示,一共有4个文件.HttpWatch Professional是单独软件,可以单独使用. 解压后有四个文件 插件安装时,只需运行httpwatc ...

  3. softmax 与 sigmoid & softmax名字的由来

    Softmax回归模型,该模型是logistic回归模型在多分类问题上的推广. 参考:http://blog.csdn.net/u014422406/article/details/52805924 ...

  4. 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS

    图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其 ...

  5. 开发板 视频04_05 ubuntu的联网及基本设置

    4g内存 如果电脑有两g,只能给1.5g 处理器可以根据实际选 usb3.0 或者 2.0 联网模式:: 桥接模式 启动式连接,,,,网是不固定的 仅主机模式,主机和虚拟机在一个网络 第三种联网,自定 ...

  6. Android中Activity切换时共享视图元素的切换动画(5.0以上)

    同一时候公布在我的博客 点此进入 背景 说来这个的背景很easy,常常在使用图片列表的时候就会想,假设"列表中的图片放大到整个屏幕"作为 Activity 的补间动画.就很完美了. ...

  7. 对照jQuery和AngularJS的不同思维模

    对照jQuery和AngularJS的不同思维模 Question 如果我已经熟悉了怎样使用jQuery来开发client应用.我如今打算使用AngularJS.请描写叙述一下有那些思维模式方面的东西 ...

  8. FreeMarker分页组件监听器

    分页组件监听器 /*  * project名:    * 包     名: com.companyName.dhm.iepgm.common.taglib  * 文 件名: PaginatedList ...

  9. wikioi 1051哈希表

    题目描写叙述 Description 给出了N个单词,已经按长度排好了序.假设某单词i是某单词j的前缀,i->j算一次接龙(两个同样的单词不能算接龙). 你的任务是:对于输入的单词,找出最长的龙 ...

  10. [AngularJS] Directive for top scroll bar

    angular.directive('dblScroll', dblScroll) dblSroll.$inject = [ '$timeout' ]; function dblScroll($tim ...