matrix
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 143 Accepted Submission(s): 97
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 a1∗a2+a3∗a4+…+a2k−1∗a2k. What is the minimum of the cost?
Input
Several test cases(about 5)
For each cases, first come 2 integers, n,m(1≤n≤1000,1≤m≤1000)
N+m is an odd number.
Then follows n lines with m numbers ai,j(1≤ai≤100)
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
题意:
有一个矩阵,从(1,1)走到(n,m)使得a1∗a2+a3∗a4+…+a2k−1∗a2k.最小。
题解:
典型的DP,dp[i][j]为从(1,1)到(i,j)得到的最小权重,那么可以知道。可能是从(i-1,j)过来的,也可能是从(i,j-1)过来的。由于对于(i-1,j)和(i,j-1)也可能是从这两个方向过来的。所以有四种状态,那么每次我们选一个最小的递推就可以了。 。当时比赛做这个题的时候脑子发热。 。结果数组越界没看出来。 。wa了9次。 。现在在hdu上AC了。现把AC代码贴出来。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define F(i,a,b) for(int i = a;i<=b;i++)
#define FI(i,a,b) for(int i = a;i>=b;i--)
using namespace std;
int a[1010][1010];
int dp[1010][1010];
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
F(i,2,m+1)
F(j,2,n+1)
scanf("%d",&a[i][j]);
memset(dp,0x3f,sizeof(dp));
for(int i = 3;i<=n+1;i+=2)
if(i==3)
dp[2][i] = a[2][i]*a[2][i-1];
else
dp[2][i] = a[2][i]*a[2][i-1] + dp[2][i-2];
for(int i = 3;i<=m+1;i+=2)
if(i==3)
dp[i][2] = a[i][2]*a[i-1][2];
else
dp[i][2] = a[i][2]*a[i-1][2] + dp[i-2][2];
F(i,3,m+1){
for(int j = (i)%2+3;j<=n+1;j+=2){
int tem1 = a[i-1][j]*a[i][j]+dp[i-2][j];
int tem2 = a[i-1][j]*a[i][j]+dp[i-1][j-1];
int tem3 = a[i][j-1]*a[i][j]+dp[i-1][j-1];
int tem4 = a[i][j-1]*a[i][j]+dp[i][j-2];
dp[i][j] = min(min(tem1,tem2),min(tem3,tem4));
}
}
printf("%d\n",dp[m+1][n+1]);
}
return 0;
}