洛谷 P3800 Power收集

简介: 题目背景 据说在红雾异变时,博丽灵梦单身前往红魔馆,用十分强硬的手段将事件解决了。 然而当时灵梦在Power达到MAX之前,不具有“上线收点”的能力,所以她想要知道她能收集多少P点,然而这个问题她答不上来,于是她找到了学OI的你。

题目背景

据说在红雾异变时,博丽灵梦单身前往红魔馆,用十分强硬的手段将事件解决了。

然而当时灵梦在Power达到MAX之前,不具有“上线收点”的能力,所以她想要知道她能收集多少P点,然而这个问题她答不上来,于是她找到了学OI的你。

题目描述

可以把游戏界面理解成一个N行M列的棋盘,有K个格子上有P点,其价值为val(i,j)

初始灵梦可以选择在第一行的任意一个格子出发,每秒她必须下移一格。

灵梦具有一个左右移动的速度T,可以使她每秒向左或右移动至多T格,也可以不移动,并且不能折返。移动可视为瞬间完成,不经过路途上的点,只能获得目标格子的P点。

求最终她能获得的POWER值最大是多少?

输入输出格式

输入格式:

 

第一行四个数字,N,M,K,T

接下来K行每行3个数字x,y,v,代表第x行第y列有一个val为v的P点,数据保证一个格子上最多只有1个P点。

 

输出格式:

 

一个数字

 

输入输出样例

输入样例#1:
3 3 4 1
1 1 3
1 2 1
2 2 3
3 3 3
输出样例#1:
9

说明

对于40%的测试点,1<=N,M,T,K<=200

对于100%的测试点,1<=N,M,T,K<=4000

v<=100,N,M,K,T均为整数

by-szc

 

解题思路

  典型的DP,我想到的有以下两种思路

    1、类似于这道题,可以从下到上一行行地填 f 数组,对于一行中的每一个,容易想到暴力搜索下一行从哪里转移过来,复杂度$O(nmt)$,然后就爆了。于是咋办呢?发现我们填$f[i][j]$时,搜了一遍$f[i+1][j-t]$到$f[i+1][j+t]$(不要在意边界溢出,特判一下就是了),然后填$f[i][j+1]$时,除了搜$f[i+1][j+t+1]$之外,又搜了一遍$f[i+1][j-t+1]$到$f[i+1][j+t]$,重复好多啊,于是怎么办呢?就想到了这题,给一个序列,求所有一定长度的区间中的最值,嗯,RMQ,可以用st表,也可以用单调队列,这里套在每一行上,总复杂度就分别是$O(nmlog_2m)$(套st表)$O(nm)$(套单调队列),于是,st表有点虚啊,常数很大的同学可能就卡不过去了,而且st表空间$O(mlog_m)$,单调队列空间$O(t)$,还有……单调队列比st表好写太多了,果断单调队列,见下面第一个代码,最慢一个点862ms,怪不得出题人把时限开到2s,放了这个大众的思路

    2、和打鼹鼠这题很像,可以看看我这篇博文。存下所有power的信息,然后按照行号、列号排个序,然后就类似最长不下降序列的DP做法了,每拓展一个位置,就向前扫描已经拓展的所有的位置,看看能从哪里来到这里,如果速度、时间都满足,就刷新最大值吧。见以下代码二。这个的时间复杂度$O(k^2)$,和上面那个单调队列是同阶的,但是这个思路实际用时是上面的二分之一,占用空间是上面的快十分之一,代码量是上面的二分之一,果然$\mbox{think twice, code once.}$啊

源代码

代码一(单调队列)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,k,t;
int a[4002][4002]={0},f[4002][4002]={0},q[4002]={0};

void work(int i)
{
    int l=0,r=0;
    //memset(q,0,sizeof(q));
    for(int j=1;j<=m;j++)
    {
        while(l<r&&f[i+1][q[r-1]]<f[i+1][j]) r--;
        q[r++]=j;
        while(l<r&&q[l]<j-t) l++;
        f[i][j]=f[i+1][q[l]];
    }
    l=0,r=0;
    //memset(q,0,sizeof(q));
    for(int j=m;j>=1;j--)
    {
        while(l<r&&f[i+1][q[r-1]]<f[i+1][j]) r--;
        q[r++]=j;
        while(l<r&&q[l]>j+t) l++;
        f[i][j]=max(f[i][j],f[i+1][q[l]]);
    }
    for(int j=1;j<=m;j++)
        f[i][j]+=a[i][j];
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&k,&t);
    for(int i=1,u,v,w;i<=k;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        a[u][v]=w;
    }
    for(int i=1;i<=m;i++) f[n][i]=a[n][i];
    for(int i=n-1;i>0;i--)
        work(i);
    int ans=-1;
    for(int j=1;j<=m;j++)
        ans=max(ans,f[1][j]);
    
    printf("%d",ans);
    return 0;
}

代码二

#include<bits/stdc++.h>
using namespace std;
int n,m,k,t;
struct Edge{
    int x,y,val;
}a[4005];
int cmp(Edge X,Edge Y)
{
    return X.x<Y.x;
}
int f[4005]={0};
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    for (int i=1;i<=k;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].val);
    sort(a+1,a+1+k,cmp);
    int ans=0;
    for (int i=1;i<=k;i++)
    {
        dp[i]=a[i].val;
        for (int j=1;j<i;j++)
            if (abs(a[i].y-a[j].y)<=t*abs(a[i].x-a[j].x))
                f[i]=max(f[i],f[j]+a[i].val);
        ans=max(ans,f[i]);
    }
    printf("%d",ans);
    return 0;
}

哇,简直就是打鼹鼠的代码复制过来啊,那题不排序但这题排序是因为那题输入按时间顺序,这个没说按顺序

目录
相关文章
|
11天前
|
存储
R语言结构方程SEM中的power analysis 效能检验分析
R语言结构方程SEM中的power analysis 效能检验分析
33 0
|
2月前
|
C++
【PTA】​L1-069 胎压监测 ​ (C++)
【PTA】​L1-069 胎压监测 ​ (C++)
46 0
【PTA】​L1-069 胎压监测 ​ (C++)
|
7月前
|
Go
Shortest Path with Obstacle( CodeForces - 1547A )(模拟)
Shortest Path with Obstacle( CodeForces - 1547A )(模拟)
28 0
|
11月前
|
测试技术
【Power平台】Power Apps项目规划阶段(3):任务和任务的人物,时间,地点
【Power平台】Power Apps项目规划阶段(3):任务和任务的人物,时间,地点
|
11月前
|
测试技术 BI
【Power平台】Power Apps项目规划阶段(4):识别活动
【Power平台】Power Apps项目规划阶段(4):识别活动
|
决策智能 Windows
运筹优化学习01:Lingo入门与错误列表分析(二)
运筹优化学习01:Lingo入门与错误列表分析
运筹优化学习01:Lingo入门与错误列表分析(二)
|
决策智能
运筹优化学习01:Lingo入门与错误列表分析(一)
运筹优化学习01:Lingo入门与错误列表分析
运筹优化学习01:Lingo入门与错误列表分析(一)
|
决策智能
运筹优化学习01:Lingo入门与错误列表分析(三)
运筹优化学习01:Lingo入门与错误列表分析
运筹优化学习01:Lingo入门与错误列表分析(三)
|
机器学习/深度学习 算法 数据可视化
使用简单算法两小时实现猎杀乌姆帕斯(Hunt the Wumpus)Python小游戏
使用Python语言可视化实现1973 年开发的一款基于文本的冒险游戏。 原著较为复杂,这里我们作出如下简化: 1. 原著十二面体可以展开为拥有20个顶点(洞穴)的地图。我们简化为更简单的 N*N 矩形地图。每个点代表一个洞穴。暂定为 5 x 5 共25个洞穴。 2. 每个洞穴(点)上下左右四通(非八达)🤪 3. 仅拥有一颗箭,即只有一次命中机会。如果错过未能将怪兽消灭即失败。 4. 如果不慎跌入怪兽洞也算失败。😏 5. 该地图不会出现 无底洞, 超级蝙蝠 等其它元素。😝 6. 隐藏信息,怪兽的洞穴是不可见的,当接近怪兽洞穴一个格子的距离时,会提示“你嗅到了乌姆帕斯的气息”。
200 0
使用简单算法两小时实现猎杀乌姆帕斯(Hunt the Wumpus)Python小游戏