Vijos p1002 过河 离散化距离+区间DP
2024-08-27 20:41:54
题意:一条长度为L(L <= 1e9)的桥上有N(1<= N <= 100)颗石头。桥的起点为0终点为L.一只青蛙从0开始跳,每次跳的长度在s,t(1<= s <= t <= 10)之间。问青蛙过河最少踩到的石头的数量?
思路:区间dp的感觉很强烈。。但是范围实在是太大了。并且有一种感觉就是当两颗相邻的石头之间的距离相距很远时,其中间的很大一段其实状态只是一个递推的关系,即只是传递,并没有改变一段区间的状态。并且有数学公式的支持;
p*x + (p+1)*y = Q;其中p,p+1表示跳跃的距离,x,y分别表示对于跳跃距离的次数;
当Q >= p(p-1)时,从该起点到Q之后的每一个点都能到达。证明很简单,只需要通过mod就可以得出x,y的取值;
这样直接特判s = t的情况,之后离散化距离;
当a[i] - a[i-1] >= 90(原本应该是72的,但是wa了一点...),直接mod 90即可;
被各种初始化...WA了;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
typedef __int64 ll;
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
int T,kase = ,i,j,k,n,m;
int dp[],a[],p[],tmp[];
int main()
{
MSi(dp);
int l,s,t;
read1(l);
read3(s,t,m);
rep1(i,,m) read1(a[i]);
if(s == t){
int ans = ;
rep1(i,,m) if(a[i]%s == ) ans++;
printf("%d\n",ans);
return ;
}
sort(a,a+m+);
a[] = ,a[++m] = l;
rep1(i,,m){
tmp[i] = tmp[i-] + (a[i] - a[i-])%;//递推实现离散化距离
p[tmp[i]] = ;
}
rep1(i,s,t) dp[i] = p[i];
rep1(i,*s,tmp[m]){ //这边从2*s开始
int L = max(i-t,), r = i - s;
rep1(j,L,r) dp[i] = min(dp[i],dp[j]);
if(p[i]) dp[i]++;
}
printf("%d\n",dp[tmp[m]]-);//设置了L处也有石头
return ;
}
最新文章
- 为什么kafka使用磁盘而不是内存
- HTML的FormData对象
- 【Shell脚本】怎样表示一个for循环
- Entity Framework Code First (四)Fluent API - 配置属性/类型
- 【Git】笔记2
- hibernate映射文件one-to-one
- IMAP收邮件
- 恢复被win7覆盖的Ubuntu Grub
- Java中的异常处理(二)
- JVM 学习笔记(二)
- Asp.net MVC Web.config配置技巧
- Swift的初始化方法
- C#中字符串的处理,对象的引用及继承(Tenth day)
- VC程序快速删除自己(可能做升级程序的时候有用)
- cocos2d-x CCNode类
- 简单介绍移动端CSS3单位rem的用法
- Java表达式中的那些坑
- New UWP Community Toolkit - RangeSelector
- Zepto.js库touch模块代码解析
- Windows 计划任务