列表

详情


NC214520. 爬塔

描述

高川最喜欢的游戏当属 Slay the Spire,这是一款爬塔游戏,你需要从一座塔的底部一直爬到顶部,在爬塔的过程中,塔的每一层都有许多的宝物等你来拿。

高川从塔的左侧开始攀爬,从底部爬到顶部,再从右侧从顶部逐步下到底部。塔总共有 n 层,每一层都有很多宝物从左到右排列。在左侧攀爬时,他只能从每层的最左边按顺序取宝物,在右侧下降时,他只能从每层的最右边按顺序取宝物。每个宝物都有一个价值,他最多拿 m 个宝物,他想知道自己从塔上下来时,最多可以拿的宝物价值和是多少。

输入描述

第一行输入两个正整数  。表示塔的层数和最多能选的个数。

接下来 n 行,每行先输入一个数字 x。表示这一层宝物的个数。接下来输入 x 个正整数,表示每个宝物的权重 c。




输入保证可挑选的物品大于等于 m 个.

输出描述

输出一个整数表示高川能拿走的最大价值和.

示例1

输入:

2 3
2 3 2
4 1 4 1 5

输出:

10

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 89ms, 内存消耗: 612K, 提交时间: 2023-02-10 11:08:37

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e2+10;
const int maxm = 1e4+10;

int a[maxn][maxn];
int x[maxn],ans[maxn][maxn];
int pref[maxn][maxn],suf[maxn][maxn];
int dp[maxm];

int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&x[i]);
		for(int j=1;j<=x[i];j++){
			scanf("%d",&a[i][j]);
			pref[i][j]=pref[i][j-1]+a[i][j];
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=x[i];j>=1;j--)
			suf[i][j]=suf[i][j+1]+a[i][j];

	for(int i=1;i<=n;i++)
		for(int j=0;j<=x[i];j++)
			for(int k=0;j+k<=x[i];k++)
				ans[i][j+k]=max(ans[i][j+k],pref[i][j]+suf[i][x[i]-k+1]);

	for(int i=1;i<=n;i++)
		for(int j=m;j>0;j--)
			for(int k=x[i];k>0;k--)
				if(k<=j)
					dp[j]=max(dp[j],dp[j-k]+ans[i][k]);

	printf("%d\n",dp[m]);
	return 0;
}

C++(clang++11) 解法, 执行用时: 33ms, 内存消耗: 2344K, 提交时间: 2020-12-05 18:54:42

#include<bits/stdc++.h>
using namespace std;
int ss,n,m,x[200],a,sum[200][200],d[200][200],dp[110][10010],sx[200];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x[i]);
		sx[i]=sx[i-1]+x[i];
		for(int j=1;j<=x[i];j++)scanf("%d",&a),sum[i][j]=sum[i][j-1]+a;
	}
	for(int i=1;i<=n;i++)for(int j=0;j<=x[i];j++)for(int k=0;k<=j;k++)d[i][j]=max(d[i][j],sum[i][k]+sum[i][x[i]]-sum[i][x[i]-(j-k)]);
	for(int i=1;i<=n;i++)for(int j=0;j<=sx[i];j++)for(int k=0;k<=min(j,x[i]);k++)dp[i][j]=max(dp[i-1][j-k]+d[i][k],dp[i][j]);
	cout<<dp[n][m]<<endl;
	return 0;
}

上一题