当前位置: 首页 > news >正文

【LGR-234-Div.3】洛谷网校 7 月 CSP-J 模拟月赛 Cfz Round 6 「Cfz Round 6」Imaichi

题目重现

原题链接

题目背景

わがままで生きるくらいが ちょうどいい
随心任性而活 这样就好

笑っていたい いまいちでもいい
我想要微笑 就算不够完美也好

题目描述

Yuki 喜欢旅行。不过她是个宅女,所以她打算在提瓦特大陆旅行。

提瓦特大陆可以被看做一个n行 m 列的方格图,每个方格内都有一个整数 ai,j​。我们用(i,j)表示第 i 行第 j 列的方格。

初始时,Yuki 有s个摩拉。她会从方格图的第1行选择一个方格作为旅程起点,开始她的旅程。

接下来,Yuki 可以进行若干次移动:

  • 如果 Yuki 位于方格图的前 (n−1) 行,则她可以移动到她左侧(如果存在)、右侧(如果存在)、下侧的方格;
  • 如果 Yuki 位于方格图的第 n 行,则她不可以再移动

每次移动后,Yuki 的摩拉数量都会根据她当前位于的方格而变化。具体地,设Yuki移动后位于的方格为 (i,j),则她的摩拉数量会发生如下的变化:

  • 如果 ai,j​>0,则Yuki的摩拉数量会增加ai,j​;
  • 如果 ai,j​<0,则Yuki的摩拉数量会减少∣ai,j​∣,即减少−ai,j​;
  • 如果 ai,j​=0,则Yuki的摩拉数量不会发生变化。

Yuki可以重复经过同一个方格,并且在她每次经过某个方格时,她的摩拉数量都会变化。

如果在某次移动后,Yuki的摩拉数量变成了负数,则她会被拘留,不可以再移动

特殊地,Yuki初始位于旅程起点时,她的摩拉数量也会根据她当前位于的方格而变化。同时,由于Yuki的背包大小有限,如果在某次移动后,她的摩拉数量大于k,则她的摩拉数量会变为k。

如果Yuki到达了方格图的第n行且Yuki 的摩拉数量不为负数,则我们称Yuki完成了她的旅程。

你需要帮助 Yuki 判断,她是否可以完成她的旅程;如果可以,你还需要求出,在她完成她的旅程后,她的摩拉数量的最大值

输入格式

本题有多组测试数据。

第一行包含两个整数c,T,分别表示测试点编号和测试数据组数。样例满足c=0。

接下来依次输入每组测试数据。对于每组测试数据:

  • 第一行包含四个整数n,m,s,k。
  • 接下来n行,每行包含m个整数,其中第i行的第j个整数表示ai,j​。

输出格式

对于每组测试数据,输出一行,包含一个整数:

  • 如果Yuki可以完成她的旅程,则输出在她完成她的旅程后,她的摩拉数量的最大值;
  • 如果Yuki不可以完成她的旅程,则输出−1。

输入输出样例

输入

0 2
3 3 1 5
2 -1 0
-3 -1 -1
-1 1 -2
2 3 1 3
-3 1 -1
0 -3 -2

输出

4
-1

 

说明/提示

样例 1 解释

对于第 1 组测试数据:

  • 其中一种满足要求的移动路线为:(1,1)→(1,2)→(1,1)→(1,2)→(1,1)→(1,2)→(2,2)→(3,2);
  • 在移动过程中,Yuki 的摩拉数量的变化为:1(初始时的摩拉数量)→3→2→4→3→5→4→3→4;
  • 可以证明,在Yuki完成她的旅程后,她的摩拉数量的最大值为4。

对于第 2 组测试数据,显然 Yuki 无法完成她的旅程。

样例 2

见题目附件中的 journey/journey2.in 与 journey/journey2.ans。

该组样例满足测试点 4 的限制。

样例 3

见题目附件中的 journey/journey3.in 与 journey/journey3.ans。

该组样例满足测试点 8 的限制。

样例 4

见题目附件中的 journey/journey4.in 与 journey/journey4.ans。

该组样例满足测试点 10 的限制。

样例 5

见题目附件中的 journey/journey5.in 与 journey/journey5.ans。

该组样例满足测试点 14 的限制。

样例 6

见题目附件中的 journey/journey6.in 与 journey/journey6.ans。

该组样例满足测试点 15 的限制。

样例 7

见题目附件中的 journey/journey7.in 与 journey/journey7.ans。

该组样例满足测试点 16 的限制。

样例 8

见题目附件中的 journey/journey8.in 与 journey/journey8.ans。

该组样例满足测试点 20 的限制。

数据范围

对于所有测试数据:

  • 1≤T≤7;
  • 2≤n,m≤1000;
  • 0≤s≤k≤109;
  • −109≤ai,j​≤109。
测试点编号n≤m≤特殊性质
122A
222
35050C
4∼55050
6200200A
7200200B
8∼9200200C
10∼11200200
1210002
1321000
1410001000A
1510001000B
16∼1710001000C
18∼2010001000
  • 特殊性质A:保证ai,j​≤0。
  • 特殊性质B:保证k=0。
  • 特殊性质C:保证不存在i,j满足1≤i,j<n且ai,j​+ai,j+1​>0。

提示

本题输入量较大,请使用较快的输入方式。

附件下载

journey.zip48.39MB

题意简述

  • 旅程起点:第1行某个方格 初态
  • 移动方向:左/右/下 这对应着状态转移方程
  • 途径获利:获该方格对应摩拉(达k饱和)
  • 旅程完成:到达第n行某个方格
  • 目标:是否可以完成旅程,完成旅程后所获摩拉的最大值

题目解答

解题关键

动态规划

状态定义

f[i][j]表示走到(i,j)所获摩拉的最大值(走不到用−1表示)。

状态转移方程

初态(第1行):f(1,i)=min(a(1,i)+s,k)

下 (i,j)→(i+1,j)

f(i,j)=max(f(i,j),min(f(i−1,j)+a(i,j),k))

左/右(不换行) (i,j1)→(i,j2)
1.路径单纯往一个方向进行转移

右往左扫,再从左往右扫

左:f(i,j)=min(f(i,j−1)+a(i,j),k)

右:f(i,j)=min(f(i,j+1)+a(i,j),k)

2.绕圈

(1)如果这个圈非正可以贪心去除。

(2)如果它绕了一个正圈,一个绕圈路径可以分成很多连续段,也就是有一个连续段之和为正,也就是存在两个相邻的数,它们的和为正。“刷摩拉”,一直达到上界k。那么可以直接把这两个格子中a非负的格子的a改成k。(比如 [−2,3]→[−2,k],[0,1]→[k,k])那么从(i,j1​)到(i,j2​)要么是直接走,要么就是需要到某个格子刷摩拉走一条左侧的折线或者右侧的折线,来刷摩拉。具体实现从左往右扫,从右往左扫,再从左往右扫即可。

(3)但是这里没有考虑既往左又往右的情况。如果左侧有两个刷币点,那么能形如x→y→x→y…的路径。够前往最近的,就可以完成满币,不必前往下一个点。右侧同理,所以对于A…S…T…B的样子,S是入口,T是出口,A,B是刷币点,可能走出来SABT,SAT的路线,本质就是看A→T,B→T哪个更优。每一次转折都一定要刷币,而关键的刷币点只有两个,所以最多转折两次,于是代码就是从左往右扫,从右往左扫,从左往右扫,从右往左扫,从左往右扫。

答案ans=max f(n,j)。

题解代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,s;ll k;
const int MAXN=1005;
int a[MAXN][MAXN];
ll f[MAXN][MAXN];
ll ans;
//快读
void read(int &a){char c;a=0;int f=1;while(!isdigit(c=getchar()))if(c=='-')f=-1;do a=a*10+c-'0';while(isdigit(c=getchar()));a*=f;
}
//快写
void write(int a){if(a<0)putchar('-'),a=-a;if(a>=10)write(a/10);putchar('0'+a%10);
}
void lr(int i){for(int j=1;j<=m;j++){if(j-1>=1&&f[i][j-1]>=0)f[i][j]=max(f[i][j],min(f[i][j-1]+a[i][j],k));}
}
void rl(int i){for(int j=m;j>=1;j--){if(j+1<=m&&f[i][j+1]>=0)f[i][j]=max(f[i][j],min(f[i][j+1]+a[i][j],k));}
}
signed main(){int c,T;cin>>c>>T;while(T--){cin>>n>>m>>s>>k;for(int i=1;i<=n;i++)for(int j=1;j<=m;++j)read(a[i][j]);for(int i=1;i<=n;i++)for(int j=1;j<=m;++j)f[i][j]=-1;for(int i=1;i<=n;i++){if(i==1){for(int j=1;j<=m;j++){f[i][j]=max(f[i][j],min((ll)s+a[i][j],k));}}else{for(int j=1;j<=m;j++){if(f[i-1][j]>=0)f[i][j]=max(f[i][j],min(f[i-1][j]+a[i][j],k));}}if(i==n)break;for(int j=1;j<=m-1;j++){if(a[i][j]+a[i][j+1]>0){if(a[i][j]>=0)a[i][j]=k;if(a[i][j+1]>=0)a[i][j+1]=k;}}lr(i);rl(i);lr(i);rl(i);lr(i);}ans=-1;for(int j=1;j<=m;j++)ans=max(ans,f[n][j]);cout<<ans<<endl;}return 0;
}
http://www.dtcms.com/a/304290.html

相关文章:

  • 【PHP】通过IP获取IP所在地理位置(免费API接口)
  • Kruskal算法
  • gTest测试框架的安装与配置
  • HammerDB:一款免费开源的数据库基准测试工具
  • YOLOv11.pt 模型转换为 TFLite 和 NCNN 模型
  • PDF转Word免费工具!批量处理PDF压缩,合并, OCR识别, 去水印, 签名等全功能详解
  • CodeRush AI 助手进驻 Visual Studio:AiGen/AiFind 亮相(三)
  • Visual Studio的妙用
  • [极客大挑战 2019]FinalSQL
  • 如何查询并访问路由器的默认网关(IP地址)?
  • 大规模矩阵构建与高级算法应用
  • Unity 编辑器开发 之 Excel导表工具
  • Python爬虫01_Requests第一血获取响应数据
  • 香橙派One安装OctoPrint 实现控制3D打印机
  • WebRTC 2025全解析:从技术原理到商业落地
  • 容器技术原理(一):从根本上认识容器镜像
  • Linux boot 目录损坏如何修复:从救援模式到系统恢复
  • APK重打包流程
  • K8s集群两者不同的对外暴露服务的方式
  • 如何迁移gitlab到另一台服务器
  • Makefile 快速入门指南
  • LangChain和LangGraph 里面的 `create_react_agent`有什么不同
  • 机器学习—逻辑回归
  • VitePress学习-自定义主题
  • 使用 Django REST Framework 构建强大的 API
  • 在依赖关系正确的情况下,执行 mvn install 提示找不到软件包
  • Python Day17 面向对象 及例题分析
  • Apache Ignite 的分布式队列(IgniteQueue)和分布式集合(IgniteSet)的介绍
  • 集成电路学习:什么是Wi-Fi无线保真度
  • 机器学习sklearn:泰坦尼克幸存预测(决策树、网格搜索找最佳参数)