列表

详情


NC214273. 炒鸡矿工

描述

最近在玩一款叫做炒鸡矿工的游戏。这个游戏的玩法建立在一个挖矿系统上。
我们认为游戏从第分钟开始,每过分钟,炒鸡矿工可以完成一次挖矿,每次可以挖重量为的金矿,准确的说,在一次挖矿中,小会在第分钟末收获重量为的金矿。炒鸡矿工在开局后会不断地重复挖矿操作,不能休息。
金矿可以储存或用于升级挖矿系统。
开局时,挖矿系统的等级为级。挖矿系统最多升到级。升级操作不消耗时间,但只能在一次挖矿开始前进行。每次升级会从第级升级到第级,需要花费重量为w_i的金矿,可以使每次挖矿的重量增加v_i,使每次挖矿的时间变成s_i。由于升级不消耗时间,小可以在一瞬间多次升级。
开局时,小拥有重量为的金矿。他想知道,在开局后恰好分钟时,他最多能拥有的金矿重量是多少。

输入描述

输入共行(或行)。
第一行包含个非负整数
第二行包含个非负整数,第个数表示w_i
第三行包含个非负整数,第个数表示
第四行包含个正整数,第个数表示
,则只有第一行。

输出描述

输出共一行,包含一个非负整数,表示最多能拥有的金矿重量。

示例1

输入:

3 2 2 1 6
1 3
3 0
3 1

输出:

17

说明:

下面给出一种可行的方案(同一行内相同颜色标记表示相关联的变化):

原站题解

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

C++(clang++11) 解法, 执行用时: 230ms, 内存消耗: 196768K, 提交时间: 2021-01-11 10:03:34

#include<bits/stdc++.h>
using namespace std;

int w[5005],s[5005];
long long ans=0,DP[5005][5005],v[5005];
int main()
{
	int i,j,p,c,n,m,t;
	scanf("%d%d%d%d%d",&p,&c,&n,&m,&t);
	memset(DP,-0x3f,sizeof(DP));
	s[0]=p,v[0]=c,DP[0][0]=m;
	for(i=1;i<=n;i++)scanf("%d",&w[i]);
	for(i=1;i<=n;i++)scanf("%lld",&v[i]),v[i]+=v[i-1];
	for(i=1;i<=n;i++)scanf("%d",&s[i]);
	for(i=0;i<=n;i++)
	{
		for(j=0;j<=t;j++)
		{
			if(j)DP[i][j]=max(DP[i][j],DP[i][j-1]);
			if(j>=s[i])DP[i][j]=max(DP[i][j],DP[i][j-s[i]]+v[i]);
			if(i&&DP[i-1][j]>=w[i])DP[i][j]=max(DP[i][j],DP[i-1][j]-w[i]);
		}
	}
	for(i=0;i<=n;i++)ans=max(ans,DP[i][t]);
	printf("%lld\n",ans);
}

上一题