一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值。
例如:3 * 3的方格。
1 3 3
2 1 3
2 2 1
能够获得的最大价值为:11。
Input
第1行:N,N为矩阵的大小。(2 <= N <= 500)
第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N <= 10000)
Output
输出能够获得的最大价值。
Sample Input
3
1 3 3
2 1 3
2 2 1
Sample Output
11
#include<iostream>
using namespace std;
const int MAXN=500+13;
int a[MAXN][MAXN];
int dp[MAXN][MAXN]={0};
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j]=max(dp[i][j-1],dp[i-1][j])+a[i][j];
} //dp[i][j]表示的是从位置(1,1)到位置(i,j)所获得的最大价值
}
cout<<dp[n][n]<<endl;
return 0;
}
矩阵取数问题 V2
一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上。第1遍时只能向下和向右走,第2遍时只能向上和向左走。两次如果经过同一个格子,则该格子的奖励只计算一次,求能够获得的最大价值。
例如:3 * 3的方格。
1 3 3
2 1 3
2 2 1
能够获得的最大价值为:17。1 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 2 -> 1。其中起点和终点的奖励只计算1次。
Input
第1行:2个数M N,中间用空格分隔,为矩阵的大小。(2 <= M, N <= 200)
第2 - N + 1行:每行M个数,中间用空格隔开,对应格子中奖励的价值。(1 <= A
<= 10000)
Output
输出能够获得的最大价值。
Sample Input
3 3
1 3 3
2 1 3
2 2 1
Sample Output
17
# include <iostream>
# include <string.h>
using namespace std;
const int maxn=200+13;
int dp[maxn*2][maxn][maxn];
int a[maxn][maxn];
int main()
{
int m,n;
cin>>m>>n;//n行 m列
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
memset(dp,0,sizeof dp);
dp[1][1][1]=a[1][1];
for(int s=2;s<n+m;s++){
for(int i=1;i<=min(s,m);i++){
if(s-i+1>n)//s-y+1=x 也就是y超过行数了
continue;
for(int j=1;j<=min(s,m);j++){
if(s-j+1>n)//s-y+1=x
continue;
dp[s][i][j]=max(max(dp[s-1][i][j], dp[s-1][i-1][j]),max(dp[s-1][i][j-1], dp[s-1][i-1][j-1]))
+(i==j ? a[s-i+1][i] : (a[s-i+1][i]+a[s-j+1][j]));
}
}
}
cout<<dp[m+n-1][m][m]<<endl;//两个的横坐标相等时,走到终点了
return 0;
}