算法学习笔记七:淘金dp(2)来自中南大学机试

在一片nm的土地上,每一块11的区域里都有一定数量的金子。这一天,你到这里来淘金,然而当地人告诉你,如果你挖了某一区域的金子,上一行,下一行,左边,右边的金子你都不能被允许挖了。那么问题来了:你最多能淘金多少?
输入
对于每组数据,第一行两个数n,m,表示土地的长和宽(1<=n,m<=200)
接下来n行,每行m个数,表示每个区域的金子数量,每个区域的金子数量不超过1000
输出
对于每组数据,输出最多得到的金子数量
样例输入
4 6
11 0 7 5 13 9
78 4 81 6 22 4
1 40 9 34 16 10
11 22 0 33 39 6
样例输出
242

思路:动态规划。
我们先看一个简化版淘金:若只有一行的金子给你挖,然后挖了一个区域的金子则这个区域左边、右边都不允许你挖了,那你最多能挖多少呢?
我们这样思考,设一个数组dp[i]记录到第i点为止可以挖的最多的金子。那么dp[i]的取值一定是取dp[i-1]dp[i-2]+a[i]中的较大值。举个例子吧(设下标从1开始):a[5]={1,2,3,4,5};我们面对a[5]区域有取或者不取2种情况,如果取a[5]区域则a[4]不能取,因此我们可以得到状态方程:dp[5]=max{dp[3]+a[5],dp[4]}所以我们就得出了结论:dp[i]=max{dp[i-2]+a[i],dp[i-1]};有边界条件dp[1]=a[1];dp[2]=max{a[1],a[2]};
而本题淘金思路就是在每一行都用"简化版淘金"的思想求出一个每行的最大值,最后在每列间再使用一次这个思想求出总共的最大值。
代码:

#include<iostream>
using namespace std;
int main()
{
   
   
	int n,m;
	while(cin>>n>>m)
	{
   
   
		int i,j,a[210][210];
		long long dp[210][210];
		for(i=0<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值