hdu 5569 matrix(dp)

来源:互联网 发布:days软件 编辑:程序博客网 时间:2024/05/21 07:12

matrix

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


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 31 2 32 2 12 32 2 11 2 4
 

Sample Output
48
 
题意:从左上顶点到右下顶点,如果走的步数是偶数,消耗就为a1*a2 + a3*a4 + ,..+a2k-1 *a2k。求最小消耗,一定到达终点为偶数步。
直接状态转移,我写的转移方程有点长,看代码吧。
#include<iostream>#include<algorithm>#include<cstdio>#include<queue>#include<map>#include<vector>#include<cstring>using namespace std;typedef long long ll;int num[1100][1100];ll dp[1100][1100];int main(){    int n, m;    while(cin>>n>>m)    {        memset(dp, 127, sizeof(dp));        for(int i = 1; i<=n; i++)            for(int j = 1; j<=m; j++)                scanf("%d", &num[i][j]);        dp[1][1] = num[1][1];        for(int i = 1; i<=max(n, m); i++)        {            dp[0][i] = 0;            dp[i][0] = 0;        }        for(int i = 1; i<=n; i++)            for(int j = 1; j<=m; j++)            {                if(i == 1 && j == 1)                    continue;                if(j == 1)                {                    if((i+j-1)%2==0)                        dp[i][j] = dp[i-2][j] + num[i][j]*num[i-1][j];//矩阵的边界的时候<span style="font-family: Arial, Helvetica, sans-serif;">,只能从一个状态转移过来</span>                    continue;                }                else if(i == 1)                {                    if((i+j-1)%2==0)                        dp[i][j] = dp[i][j-2] + num[i][j-1]*num[i][j];//同上                    continue;                }                else if(i == 2)                    dp[i][j] = min(dp[i][j-2] + num[i][j] * num[i][j-1],                                    dp[i-1][j-1] + min(num[i][j] * num[i][j-1], num[i][j] * num[i-1][j]));//可以从3个状态转移过来                else if(j == 2)                    dp[i][j] = min(dp[i-2][j] + num[i][j] * num[i-1][j],                                    dp[i-1][j-1] + min(num[i][j] * num[i][j-1], num[i][j] * num[i-1][j]));                else if((i+j-1)%2==0)                {                    dp[i][j] = min(min(dp[i-2][j], dp[i-1][j-1])+num[i-1][j]*num[i][j],                                   min(dp[i][j-2], dp[i-1][j-1])+num[i][j]*num[i][j-1]);//可以从4个状态转移过来                }            }        cout<<dp[n][m]<<endl;    }    return 0;}


0 0