#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
long long f[1000002];
bool vis[1000002];
struct p{
long long x;
int id;
bool operator <(const p &a) const{
return x>a.x;}
};
priority_queue<p>q;
int n,l,r;
int main(){
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
scanf("%d",&f[i]);
p now;
now.id=0;
now.x=0;
vis[0]=1;
q.push(now);
for(int i=l+1;i<=n;i++)
{
now=q.top();
while(q.size()>1&&now.id+r+1<i) q.pop(),now=q.top();
if(q.size()!=1||now.id+r+1>=i)
{
vis[i]=1;
f[i]+=now.x;
}
if(vis[i-l])
{
now.id=i-l;
now.x=f[i-l];
}
q.push(now);
}
if(vis[n]) printf("%lld",f[n]);
else printf("-1");
return 0;
}
跳棋
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
long long f[1000002];
bool vis[1000002];
struct p{
long long x;
int id;
bool operator <(const p &a) const{
return x>a.x;}
};
priority_queue<p>q;
int n,l,r;
int main(){
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
scanf("%d",&f[i]);
p now;
now.id=0;
now.x=0;
vis[0]=1;
q.push(now);
for(int i=l+1;i<=n;i++)
{
now=q.top();
while(q.size()>1&&now.id+r+1<i) q.pop(),now=q.top();
if(q.size()!=1||now.id+r+1>=i)
{
vis[i]=1;
f[i]+=now.x;
}
if(vis[i-l])
{
now.id=i-l;
now.x=f[i-l];
}
q.push(now);
}
if(vis[n]) printf("%lld",f[n]);
else printf("-1");
return 0;
}
Description
小明迷恋上了一个新的跳棋游戏,游戏规则如下:棋盘是一排从0开始,顺序编号的格子, 游戏开始时你位于0号格子,你每次只能往编号大的格子跳,而且你每次至少需要跳过L个格 子,至多只能跳过R个格子。每个格子都有一个给定的伤害值,显然你希望得到的伤害值越 少越好。
你能告诉小明他当他跳到最后一个格子时受到的累积伤害值最小为多少吗? 如果无论如何小明都无法跳到最后一个格子,这个时候你需要输出"-1"。 注:从i号格子跳过x个格子表示从i号格子跳到第i+x+1号格子。
你能告诉小明他当他跳到最后一个格子时受到的累积伤害值最小为多少吗? 如果无论如何小明都无法跳到最后一个格子,这个时候你需要输出"-1"。 注:从i号格子跳过x个格子表示从i号格子跳到第i+x+1号格子。
Input
第一行有三个整数n、L和R,n表示格子的编号从0到n。L和R表示最少需要跳过的格子数和最多能够跳过的格子数。
第二行有n个正整数,两个数字间用空格隔开,表示每个格子的伤害值。
第二行有n个正整数,两个数字间用空格隔开,表示每个格子的伤害值。
Output
仅有一个整数,表示受到的最小伤害值,保证结果小于 maxlongint。
Sample Input
10 2 6
1 3 5 7 9 2 4 6 8 10
1 3 5 7 9 2 4 6 8 10
Sample Output
12
Sample Explanation
![](https://i-blog.csdnimg.cn/blog_migrate/5012569637f8b68cdc717964670c189e.png)
Hint
50%的数据:1 ≤ n ≤ 1000;
65%的数据:1 ≤ n ≤ 10000;
100%的数据:1 ≤ n ≤ 1000000,1 ≤ L ≤ R ≤ n, 其中有15%的数据:1 ≤ n ≤ 1000000,1 ≤ L ≤ R ≤ 10 。
65%的数据:1 ≤ n ≤ 10000;
100%的数据:1 ≤ n ≤ 1000000,1 ≤ L ≤ R ≤ n, 其中有15%的数据:1 ≤ n ≤ 1000000,1 ≤ L ≤ R ≤ 10 。
好吧,这是我第一篇博文,这题其实80分不难,应该是很简单,f[i]=f[i]+min{f[j]|j是i能达到的}
但是有个坑,好吧我就被坑了,就是不清楚终点是否能到达,即是否输出-1。
好吧,说说满分算法,一看到一个L和R,不能想到这是类似于滑动窗口;
我们可以用堆或者单调队列维护,好吧,我用的是单调队列,比较简单……
话不多说,看代码吧。