hdu 5569 matrix(dp) - dblank

# 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

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

#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;
}