sdnu1038

1038.收集宝藏

Time Limit: 1500 MS    Memory Limit: 32768 KB
Total Submission(s): 280    Accepted Submission(s): 142

Description

有一个n*n的矩阵,矩阵每个格子中都有一些宝藏,从左上角(1, 1)出发,每次只能向下或者向右移动一格,已知每个格子中宝藏的价值,求走到右下角(n, n)时能收集到的宝藏的总最大价值。

Input

第一行为一个整数n(1 <= n <= 1000),表示矩阵的行、列数。

接下来n行,每行n个整数,每个整数表示当前格子的宝藏价值(不超过10000)。

Output

一个整数,表示能收集到的宝藏的最大总价值。

Sample Input

4
1 2 3 10
3 4 1 1
5 2 1 1
1 3 1 1

Sample Output

19

Source

Unknown

这个题简单分析下:正方形矩阵由左上角走到右下角求获得宝藏的最大值。

两种方法1.记忆化搜索不断记录,不断比较找到最大的方式.

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h> 
using namespace std;
int u[1010][1010];
int sum[1000][1000];
int n;
int rec(int a,int b)
{
	if(sum[a][b]!=-1)
		return sum[a][b];/*当遍历到矩阵外或者已经有了sum值则直接返回。*/ 
	/*在这里我们不必担心返回的会不会不是最大值,因为下面的遍历每一次都是获得的其最大值。因而在这个sum数组中的也一定是最大值*/ 
//	if(sum[a][b]>=0)
//		return sum[a][b];
	int nx = rec(a+1,b);
	int ny = rec(a,b+1);
	sum[a][b] = max(nx,ny)+u[a][b];
	return sum[a][b];
	
}
int main()
{

	scanf("%d",&n);
	memset(sum,0,sizeof(sum));
	for(int i = 0;i<n;i++)
	{
		for(int j = 0;j<n;j++)
		{
			scanf("%d",&u[i][j]);
			sum[i][j]=-1;//记录矩阵。有矩阵的地方记录为-1. 
		}
	}
	int res = rec(0,0);
	printf("%d\n",res);
	
} 

2.动态规划

递推方程

sum[i][j] = max(sum[i-1][j],sum[i][j-1]) +u[i][j];

可以想象下矩阵除两条边边界外而且只能左移和下移。所以满足上述递推式。所以我们只需特殊处理两条边边界即可。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h> 
using namespace std;
int u[1010][1010];
int sum[1000][1000];
int n;
int main()
{

	scanf("%d",&n);
	memset(sum,0,sizeof(sum));
	for(int i = 0;i<n;i++)
	{
		for(int j = 0;j<n;j++)
		{
			scanf("%d",&u[i][j]);
		}
	}
	sum[0][0] = u[0][0];
	for(int i = 1;i<n;i++)
	{
		sum[0][i] = sum[0][i-1]+u[0][i];/*处理边界问题因为只有边界不满足递推式*/ 
		sum[i][0] = sum[i-1][0]+u[i][0];
	}
	for(int i = 1;i<n;i++)
	{
		for(int j =1;j<n;j++)
		{	
			sum[i][j] = max(sum[i-1][j],sum[i][j-1]) +u[i][j];
		} 	
	}
	printf("%d\n",sum[n-1][n-1]);
	
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值