[GESP202312 六级] 闯关游戏

视频讲解:GESP202312 六级 闯关游戏-信息学奥赛GESP等级考试真题解析

一、原题

题目描述

你来到了一个闯关游戏。

这个游戏总共有 N 关,每关都有 M 个通道,你需要选择一个通道并通往后续关卡。其中,第 i 个通道可以让你前进 ai​ 关,也就是说,如果你现在在第 x 关,那么选择第 i 个通道后,你将直接来到第 x+ai​ 关(特别地,如果 x+ai​≥N,那么你就通关了)。此外,当你顺利离开第 s 关时,你还将获得 bs​ 分。

游戏开始时,你在第 0 关。请问,你通关时最多能获得多少总分。

输入格式

第一行两个整数 N,M,分别表示关卡数量和每关的通道数量。

接下来一行 M 个用单个空格隔开的整数 a0​,a1​⋯,aM−1​。保证 1≤ai​≤N。

接下来一行 N 个用单个空格隔开的整数 b0​,b1​⋯,bN−1​。保证 ∣bi​∣≤10^5。

输出格式

一行一个整数,表示你通关时最多能够获得的分数。

输入输出样例

输入 #1

bash 复制代码
6 2 
2 3
1 0 30 100 30 30

输出 #1

bash 复制代码
131

输入 #2

bash 复制代码
6 2
2 3
1 0 30 100 30 -1

输出 #2

bash 复制代码
101

说明/提示

样例解释 1

你可以在第 0 关选择第 1 个通道,获得 1 分并来到第 3 关;随后再选择第 0 个通道,获得 100 分并来到第 5 关;最后任选一个通道,都可以获得 30 分并通关。如此,总得分为 1+100+30=131。

样例解释 2

请注意,一些关卡的得分可能是负数。

数据范围

对于 20% 的测试点,保证 M=1。

对于 40% 的测试点,保证 N≤20;保证 M≤2。

对于所有测试点,保证 1≤N≤10^4;保证 1≤M≤100。

二、做题思路

1)填充数据

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//1.1)确定关卡数量n 通道数量m
	int n,m;cin>>n>>m;
	//1.2)填充m个通道 排序 
	int a[110]={};
	for(int i=1;i<=m;i++) cin>>a[i];
	sort(a+1,a+m+1);
	//1.3)填充0-n-1个关卡的分数
	int b[10005]={};
	for(int i=0;i<=n-1;i++) cin>>b[i];
	return 0;
} 

2)动态规划:求出当前格子的最大分数

2.1)dp初始化

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//...
	//2)动态规划:求出当前格子的最大分数
	//2.1)dp初始化
	vector<int> dp(10005,-1e9);
	dp[0]=b[0];
	return 0;
} 

2.2)从最小通道的关卡到n-1关

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//...
	//2)动态规划:求出当前格子的最大分数
	//2.1)dp初始化
	vector<int> dp(10005,-1e9);
	dp[0]=b[0];
	//2.2)从最小通道的关卡到n-1关
	for(int i=a[i];i<=n-1;i++){
		
	}
	return 0;
} 

2.3)循环每个通道(判断能否到达)

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//...
	//2)动态规划:求出当前格子的最大分数
	//2.1)dp初始化
	vector<int> dp(10005,-1e9);
	dp[0]=b[0];
	//2.2)从最小通道的关卡到n-1关
	for(int i=a[i];i<=n-1;i++){
		//2.3)循环每个通道(判断能否到达)
		for(int j=1;j<=m;j++){
			if(dp[i-a[j]]!=-1e9&&i-a[j]>=0){
				dp[i]=max(dp[i],dp[i-a[j]]+b[i]);
			}
		}
	}
	return 0;
} 

2.4)循环最大通道前的分数,找最大值

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//...
	//2)动态规划:求出当前格子的最大分数
	//2.1)dp初始化
	vector<int> dp(10005,-1e9);
	dp[0]=b[0];
	//2.2)从最小通道的关卡到n-1关
	for(int i=a[i];i<=n-1;i++){
		//2.3)循环每个通道(判断能否到达)
		for(int j=1;j<=m;j++){
			if(dp[i-a[j]]!=-1e9&&i-a[j]>=0){
				dp[i]=max(dp[i],dp[i-a[j]]+b[i]);
			}
		}
	}
	//2.4)循环最大通道前的分数,找最大值
	int ans=INT_MIN;
	for(int i=n-a[m];i<=n-1;i++){
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	return 0;
} 

三、答案

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//1.1)确定关卡数量n 通道数量m
	int n,m;cin>>n>>m;
	//1.2)填充m个通道 排序 
	int a[110]={};
	for(int i=1;i<=m;i++) cin>>a[i];
	sort(a+1,a+m+1);
	//1.3)填充0-n-1个关卡的分数
	int b[10005]={};
	for(int i=0;i<=n-1;i++) cin>>b[i];
	//2)动态规划:求出当前格子的最大分数
	//2.1)dp初始化
	vector<int> dp(10005,-1e9);
	dp[0]=b[0];
	//2.2)从最小通道的关卡到n-1关
	for(int i=a[i];i<=n-1;i++){
		//2.3)循环每个通道(判断能否到达)
		for(int j=1;j<=m;j++){
			if(dp[i-a[j]]!=-1e9&&i-a[j]>=0){
				dp[i]=max(dp[i],dp[i-a[j]]+b[i]);
			}
		}
	}
	//2.4)循环最大通道前的分数,找最大值
	int ans=INT_MIN;
	for(int i=n-a[m];i<=n-1;i++){
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	return 0;
} 
相关推荐
德迅云安全-上官4 小时前
德迅游戏盾:面向 TCP 业务的分布式云安全防护方案
分布式·tcp/ip·游戏
科技那些事儿5 小时前
旗舰游戏本 CPU 对决:锐龙 9 9955HX 对比酷睿 Ultra 9 275HX
游戏·智能手机·智能电视
njsgcs6 小时前
老滚5 文本替换中文简体 仓库加经验glm5.3f
游戏
I Am a robert girl20 小时前
从 GameHorizon 拆解多时间尺度游戏评测:数据管线、离线基准与在线回放的三层设计
数据库·游戏·多时间尺度·数据管线·游戏评测·离线基准·在线回放
大囚长21 小时前
AI意图预测与游戏全球同服对战的超光速零延迟探究
人工智能·游戏
qq3621967051 天前
OBB 数据包是什么?大型游戏 APK 装完闪退的元凶(2026)
游戏
xiaolang_8616_wjl1 天前
c++游戏_宝可梦大世界(源代码)
开发语言·c++·游戏
凯基迪科技2 天前
Unity游戏加密锁逆向方案、选型与攻防分析
游戏·unity·游戏引擎
Solange__2 天前
航天科普怎么用AI生成3D场景?从科学约束、尺度分层到网页展示的完整方案
图像处理·人工智能·游戏·3d·ai·自然语言处理·关卡设计