BestCoder Round #63 (div.2) HDOJ5569 matrix(dp)

32 篇文章 0 订阅
29 篇文章 0 订阅

matrix

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 304    Accepted Submission(s): 187


Problem Description
Given a matrix with  n  rows and  m  columns (  n+m  is an odd number ), at first , you begin with the number at top-left corner (1,1) and you want to go to the number at bottom-right corner (n,m). And you must go right or go down every steps. Let the numbers you go through become an array  a1,a2,...,a2k . The cost is  a1a2+a3a4+...+a2k1a2k . What is the minimum of the cost?
 

Input
Several test cases(about  5 )

For each cases, first come 2 integers,  n,m(1n1000,1m1000)

N+m is an odd number.

Then follows  n  lines with  m  numbers  ai,j(1ai100)
 

Output
For each cases, please output an integer in a line as the answer.
 

Sample Input
  
  
2 3 1 2 3 2 2 1 2 3 2 2 1 1 2 4
 

Sample Output
  
  
4 8
 

Source
 



题目链接:点击打开链接

动态规划题目, dp[i][j]表示第i, j位置的贡献, 当时不会处理dp数组和矩阵. (i + j)为奇数时, 进行状态转移即可.

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1005;
int n, m;
ll maze[MAXN][MAXN], dp[MAXN][MAXN];
int main(int argc, char const *argv[])
{
	while(scanf("%d%d", &n, &m) != EOF) {
		memset(dp, 0, sizeof(dp));
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= m; ++j)
				scanf("%lld", &maze[i][j]);
		dp[1][2] = maze[1][1] * maze[1][2], dp[2][1] = maze[1][1] * maze[2][1];
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= m; ++j) {
				if((i + j) & 1) {
					if(j > 2 && dp[i][j - 2]) {
						if(dp[i][j]) dp[i][j] = min(dp[i][j], dp[i][j - 2] + maze[i][j] * maze[i][j - 1]);
						else dp[i][j] = dp[i][j - 2] + maze[i][j] * maze[i][j - 1];
					}
					if(i > 2 && dp[i - 2][j]) {
						if(dp[i][j]) dp[i][j] = min(dp[i][j], dp[i - 2][j] + maze[i][j] * maze[i - 1][j]);
						else dp[i][j] = dp[i - 2][j] + maze[i][j] * maze[i - 1][j];
					}
					if(i > 1 && j > 1 && dp[i - 1][j - 1]) {
						if(dp[i][j]) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + min(maze[i][j - 1] * maze[i][j], maze[i - 1][j] * maze[i][j]));
						else dp[i][j] = dp[i - 1][j - 1] + min(maze[i][j - 1] * maze[i][j], maze[i - 1][j] * maze[i][j]);
					}
				}
			}
		printf("%lld\n", dp[n][m]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值