Golang实现宝藏最高价值问题(动态规划)

题目来源 360春招笔试题2021年
X星人发现了一个藏宝图,在藏宝图中标注了N个宝库的位置。这N个宝库连成了一条直线,每个宝库都有若干枚金币。

X星人决定乘坐热气球去收集金币,热气球每次最多只能飞行M千米(假设热气球在飞行过程中并不会发生故障)此外,由于设计上的缺陷,热气球最多只能启动K次。

X星人带着热气球来到了第1个宝库(达到第1个宝库时热气球尚未启动),收集完第1个宝库的金币后将启动热气球前往下一个宝库。如果他决定收集某一个宝库的金币,必须停下热气球,收集完之后再重新启动热气球。当然,X星人每到一个宝库是一定会拿走这个宝库所有金币的。

已知每一个宝库距离第1个宝库的距离(单位:千米)和宝库的金币数量。

请问X星人最多可以收集到多少枚金币?

单组输入。
第1行输入三个正整数N、M和K,分别表示宝库的数量、热气球每次最多能够飞行的距离(千米)和热气球最多可以启动的次数,三个正整数均不超过100,相邻两个正整数之间用空格隔开。
接下来N行每行包含两个整数,分别表示第1个宝库到某一个宝库的距离(千米)和这个宝库的金币枚数。(因为初始位置为第1个宝库,因此第1个宝库所对应行的第1个值为0。)
输入保证所有的宝库按照到第1个宝库的距离从近到远排列,初始位置为第1个宝库。

package main

import "fmt"

func main() {

	n, m, k := 0, 0, 0
	fmt.Scan(&n, &m, &k)
	data := make([][2]int, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&data[i][0], &data[i][1])
	}

	//DP[i][j]表示对于前i个宝箱有j次机会的最大金币数
	//边界条件DP[0][0]=data[0][1]
	dp := make([][]int, n)
	for i := range dp {
		dp[i] = make([]int, k+1)

	}
	ans := 0
	dp[0][0] = data[0][1]
	for i := 1; i < n; i++ {
		for j := 1; j < k+1; j++ {
			for l := i - 1; l >= 0; l-- {
				ans = max(ans, dp[i][j])
				if data[i][0]-data[l][0] > m {
					break
				} else {
					if dp[l][j-1] == 0 {
					} else {
						dp[i][j] = max(dp[i][j], dp[l][j-1]+data[i][1])
					}
				}
			}

		}
	}
	fmt.Println(ans)
}
func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LSY_HELLOWORLD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值