hdu 5569 matrix (dp)

http://acm.hdu.edu.cn/showproblem.php?pid=5569

matrix

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
 
问题描述
给定n*mnm(n+mn+m为奇数)的矩阵,从(1,1)(1,1)走到(n,m)(n,m)且只能往右往下走,设经过的数为a_1, a_2 ... a_{2k}a1,a2...a2k,贡献为a_1*a_2+a_3*a_4+...+a_{2k-1}*a_{2k}a1a2+a3a4+...+a2k1a2k,求最小贡献。
思路:

当是第奇数步的时候状态转移方程为dp[i][j] = min (dp[i-1][j], dp[i][j-1]);

当是第偶数步的时候状态转移方程为dp[i][j] = min (dp[i-1][j] + g[i-1][j]*g[i][j], dp[i][j-1] + g[i][j-1]*g[i][j]);

处理一次边界就可以了dp[1][1] = 0;

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <queue>
#include <stack>
#include <vector>
#include <map>

using namespace std;
typedef long long LL;

#define N 1010
#define INF 0x3f3f3f3f
#define PI acos (-1.0)
#define EPS 1e-8
#define met(a, b) memset (a, b, sizeof (a))

int dp[N][N], g[N][N];

int main ()
{
    int n, m;

    while (scanf ("%d %d", &n, &m) != EOF)
    {
        for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
        scanf ("%d", &g[i][j]);

        for (int i=0; i<=n+1; i++)
        for (int j=0; j<=m+1; j++)
        dp[i][j] = INF;

        for (int i=1; i<=n; i++)
        {
            for (int j=1; j<=m; j++)
            {
                if ((i+j)&1)
                    dp[i][j] = min (dp[i-1][j] + g[i-1][j]*g[i][j], dp[i][j-1] + g[i][j-1]*g[i][j]);
                else dp[i][j] = min (dp[i-1][j], dp[i][j-1]);
                if (i == 1 && j == 1) dp[i][j] = 0;
            }
        }
        printf ("%d\n", dp[n][m]);
    }
    return 0;
}


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_大太阳_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值