洛谷 P3800 Power收集【DP】

本文介绍了一种解决特定游戏棋盘问题的动态规划算法,玩家需在有限时间内通过棋盘并收集点数,算法关注如何高效计算出可获取的最大点数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

可以把游戏界面理解成一个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点。

输出格式:

一个数字

说明

对于40%的测试点,1<=N,M,T,K<=200
对于100%的测试点,1<=N,M,T,K<=4000
v<=100,N,M,K,T均为整数


题目分析

可能很多人第一眼看过去都以为用dp[i][j]表示走到第i行第j列三层循环就能过.
如果你第一眼不是这么想当我没说.
反正我是这样爆T六个点.

这题的突破口就在于不是每个点都有权值
所以我们只用记录那些有权值的点
然后用那些能到达当前节点的点更新当前结点最大值就好了

具体来说就是先将结点按x坐标升序排序
abs(xi−xj)∗T&gt;=abs(yi−yj)abs(x_i-x_j)*T&gt;=abs(y_i-y_j)abs(xixj)T>=abs(yiyj)
就更新dp[i]=max(dp[i],max(dp[i],dp[j]+vali)dp[i]=max(dp[i],max(dp[i],dp[j]+val_i)dp[i]=max(dp[i],max(dp[i],dp[j]+vali)

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
 
int read()
{
    int f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

int n,m,k,t;
struct node{int x,y,val;}a[5010];
int dp[5010];
int ans=-1e9;
bool cmp(node a,node b){return a.x<b.x;}

int main()
{
    n=read();m=read();k=read();t=read();
    for(int i=1;i<=k;++i)
    a[i].x=read(),a[i].y=read(),a[i].val=read();
    
    sort(a+1,a+1+k,cmp);
    dp[1]=a[1].val;
    for(int i=1;i<=k;++i)
    {
        for(int j=0;j<i;++j)
        {
            if( abs(a[i].x-a[j].x)*t >= abs(a[i].y-a[j].y) )
            dp[i]=max(dp[i],dp[j]+a[i].val);
        }
        ans=max(ans,dp[i]);
    }
    cout<<ans;
    return 0;
}
洛谷P2437是一道关于模拟火星数学计数方式的题目,在这题中你需要理解火星人独特的进制表示法,并将其转换为我们熟悉的十进制数字。 ### 题目概述 火星人在他们的生活中使用一种特殊的二进制系统来记录数值。这种二进制不同于地球上的标准二进制,它不仅包含字符`0`和`1`,还引入了额外的一个特殊符号 `-` 表示负号。因此,对于每一位来说,可以有三种状态:正的 `1`, 负的 `-1` 和零 `0` 。比如给定一个字符串 `"10-1"` ,应该按照类似三进制的方式来解析该串对应的整数值: **公式**: 数字 = Σ (ai × 3^i),其中 ai 取自集合 {-1, 0, 1} 例如: - 输入 "1-" 的含义为:1×3¹ + (-1)×3⁰ = 3 - 1 = **2** - 输入 "-10" 则代表:(-1)×3² + 0×3¹ + 0×3⁰ = -9 + 0 = **-9** --- ### C语言解决方案概览 我们可以通过循环读取每个字符并累加的方式快速实现这个问题的答案。以下是大致步骤: 1. 将字符串逆序遍历; 2. 根据当前位权重(power of three)与字母映射关系调整总和; - `'-' -> -1` - `'0' -> 0` - `'1' -> 1` #### 示例代码片段 ```c #include <stdio.h> #include <string.h> int main(){ char str[50]; scanf("%s",str); // 获取输入数据 int len=strlen(str),sum=0,power=1; for(int i=len-1;i>=0;--i){ if(str[i]=='1') sum += power; else if(str[i]=='-') sum -= power; power *=3;//更新下一位权值 } printf("%d\n",sum); return 0; } ``` 上述代码首先获取用户提供的火星文字符串,接着逐一遍历每一个字符位置同时不断乘以适当的幂次直至首位结束。 --- ### 运行测试样例 | 测试输入 | 输出结果 | |----------|-----------| | ```1-``` |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值