luoguP1502过河题解
日常吐(fei)嘈(hua)
这道题作为最近卡了我3天的dp题(最后还是在题解的帮助下冥思苦想才过掉的题),窝觉得此题肥肠之脑洞,写此博客纪念
题解
过河


先来日常手玩样例:

咦感觉怎么手玩答案都像是3的亚子???
吓得我打开了讨论组
我们发现题目没说一定要踩到石子上,所以类似0->2->4->7->10的走法也是可以的
手玩样例成功√
容易看出来这是个dp,因为走法无后效性。
那么我们思考dp式子。设\(dp[i]\)表示跳到距离原点\(i\)的地方,最少踩过的石子数。因为最终可以跳出\(L\),所以答案是\(min\{dp[i],i \in [L,L+t]\}\)。转移就是\(dp[i]=min\{dp[i-j] \}+是否有石子,j \in [s,t]\)
然后我们康康数据范围

噫,好,我炸了
显然空间是开不下的。就算用各种奇技淫巧把空间优化到开的下然后发现\(O(1e9)\)的\(dp\)它\(T\)了。
于是我们考虑用各种奇技淫巧来减小\(L\)
我们发现石子数量\(M\)相比于\(1e9\)来说小的可怜,只有100。这样一定会出现两个石子中间距离特别特别大的现象。而且\(s,t\)最大是10,显然对这些中间没有石子的区域进行dp是个很大的浪费。那么我们想办法把这些距离压缩掉。

我们来观察一下中间没有石子的区域的dp值是如何转移的。

其中\([s_i,t_i]\)是跳i步能达到的点。我们发现\(s_i=0+i\times s,t_i+i\times t\).而且发现当某个\(s_i=t_k\)时,就会产生有两个\([s_i,t_i]\)接起来辣!然后\(dp\)值也就会出现和前面相同,此时就可以压缩掉了,发现当上面的\(i=t,k=s\)时一定会出现这种局面,所以两个石子间的距离遇弱大于\(s\times t\),就可以把距离压缩成\(s\times t\)。
当然,对于\(s==t\)的情况是要特判的
因为\(s==t\),所以只能跳s的倍数,直接看s的倍数的地方有多少石子就可以了
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<ctime>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
const int inf=2147483647;
inline int read()
{
char ch=getchar();
int x=0;
bool f=0;
while(ch<'0'||ch>'9')
{
if(ch=='-') f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
int l,s,t,m,sz[109];
int dp[10000009];
int ys[10000009];
int main()
{
l=read();s=read();t=read();m=read();
for(int i=1;i<=m;i++)
sz[i]=read();
if(s==t)
{
int ans=0;
for(int i=1;i<=m;i++)
if(sz[i]%s==0) ans++;
printf("%d",ans);
return 0;
}
sort(sz+1,sz+1+m);//输入不一定按升序
int qwq=s*t;
int lst=0;
for(int i=1;i<=m;i++)//压缩距离
{
int qaq=sz[i]-lst;
lst=sz[i];
if(qaq>=qwq) qaq=qwq;
sz[i]=qaq+sz[i-1];
ys[sz[i]]=1;
}
int en=sz[m]+qwq;//考虑可以跳出l,所以最后距离要大一些
memset(dp,0x3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=en;i++)
{
for(int j=s;j<=t;j++)
if(i-j>=0) dp[i]=min(dp[i],dp[i-j]+ys[i]);//上面的dp式子
}
int ans=inf;
for(int i=sz[m];i<=en;i++)
ans=min(ans,dp[i]);
printf("%d",ans);
}
luoguP1502过河题解的更多相关文章
- P1052 过河 题解
复习dp(迪皮)的时候刷到了一道简单路径压缩的题目(一点不会qwq) 题目描述链接. 正解: 首先呢,我们看到题目,自然而然的会想到这种思路: 设状态变量dp[i]表示从第一个格子开始经过一些跳跃跳到 ...
- 洛谷P1002 过河卒 题解 动态规划
题目链接:https://www.luogu.com.cn/problem/P1002 题目大意 棋盘上\(A\)点有一个过河卒,需要走到目标\(B\)点.卒行走的规则:可以向下.或者向右.同时在棋盘 ...
- 【题解】p1809 过河问题
原题传送门 题目分析 现有n个人在东岸,要过河去西岸.开始东岸有一艘船,船最多可承载2人,过河时间以耗时最长的人所需时间为准. 给定n个人的过河时间a,求所有人从东岸到西岸所需的最短时间. 当\(n= ...
- 【题解】洛谷P1002过河卒
首先,一道入门DP 然而对于蒟蒻的我已经难到爆了好吗 第一点:动态转移方程 用DP的关键! 这题我们可以发现每一步的方案数由上面的那步加上左边的那步得到 所以自然而然的方程就出来了: f[i][k]= ...
- 题解 P1002 【过河卒】
正文 简单描述一下题意: 士兵想要过河,他每一次可以往下走一格,也可以往右走一格,但马一步走到的地方是不能走的,问走到\(n\)行,\(m\)列有多少种走法 我们显然应该先根据马的位置将不能走的格子做 ...
- 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)
题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...
- 洛谷 P1809 过河问题 题解
题面 这道题是一道贪心+DP的好题: 首先排序是一定要干的事情. 然后我们分情况处理: 1.如果剩一个人,让最小的回来接他 2.如果剩两个人,让最小的回来接,剩下的那两个人(即最大的两个人)过去,让次 ...
- 题解 P1052 【过河】
显然是\(dp\),是用\(STL\)当中的\(map\)可以做到30分 #include <bits/stdc++.h>//万能头文件 using namespace std; int ...
- 题解:2018级算法第六次上机 C6-不Nan的过河
题目描述: 样例: 实现解释: 一道因为没排序做了一个小时没做出来的二分答案模板题(手动呲牙) 知识点: 二分答案,最大值最小化 坑点: 排序,judge(mid)函数内计数的实现 其实从最长一步的最 ...
随机推荐
- Cocoapods私有库
http://www.jianshu.com/p/d6a592d6fced 1.创建两个什么都不选的远程仓库:(私有公有都可,ReadMe\ignore都不选),一个放代码,一个放源(*.podspe ...
- php 多肽实例
多态定义:只关心一个接口或者基类,而不关心一个对象的具体类.(同一类型,不同结果) 这里两个例子: 第一个,我们发现,基类定义了标准,子类进行了自我规则的实现.这是多态的一个要求.同时,这是满足重写: ...
- CH5101 LICS//hdu5904 LICS
恭喜我已经正式沦为pj组选手QwQ 标题两个题其实不一样的.这是ch 这是hdu 一.CH上的:裸题,求LICS.n<=3000 经典普及组dp题,题解烂大街了.所以对于这题,只讲细节: $ ...
- orm查询优化 MTV和MVC模型 字段的chioces参数 Ajax
目录 一.ORM查询优化 1. all()查询 2. only()/defer()方法 (1)only()方法 (2)defer()方法 3. select_related()/prefetch_re ...
- thinkPHP5.0.22初体验---request相关用法
如果浏览器要返回美观排列的json数据,可以安装火狐浏览器的插件 返回XML的数据格式 渲染模板的用法 return $this->fetch('index/index2')效果 扒掉stirp ...
- MySQL内联和外联查询
内连: 内连接是通过在查询中设置连接条件的方式,来移除查询结果集中某些数据行后的交叉连接.简单来说,就是利用条件表达式来消除交叉连接的某些数据行. 在MySQL FROM 子句中使用关键字 INNER ...
- python selenium 笔记
1.安装环境 下载python 3.6.4 第一页把最下面的环境变量勾上.第二页把 all user 勾上 直接安装到下一步 安装完成之后 cmd直接输入python 可以看到版本 2.安装 ...
- Java多线程和并发(四),线程返回值获取方式和Callable接口
目录 1.主线程等待法 2.使用Thread类的join()阻塞当前线程,等待子线程执行完毕 3.通过Callable接口实现:通过FutureTask Or线程池获取 四.线程返回值获取方式和Cal ...
- Travis CI Could not find or load main class org.gradle.wrapper.GradleWrapperMain 错误
问题 在 Travis CI 编译的时候出现 Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain ...
- CF 352 D 罗宾汉发钱 模拟题+贪心
D. Robin Hood time limit per test 1 second memory limit per test 256 megabytes input standard input ...