用方格取数的代码(稍改动)。
大佬的证明。为啥方格取数可以用传纸条代码。
方法① 注释了if(j1…)这一判断条件,将i1和i2的遍历上限设为n(行数)
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 10;
int f[N][N][N];
int n,r,c,v,m;
int w[N][N];
int main(){
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++){
for(int j =1; j <= m; j ++){
scanf("%d",&w[i][j]);
}
}
for(int k = 2; k <= m + n; k++){
for(int i1 = 1; i1 <= n; i1++){//当i1小于等于k时,if(j1<=k..)时,也能过。
for(int i2 = 1; i2 <= n; i2++){
int j1 = k - i1, j2 = k - i2;
int &x = f[k][i1][i2];
int t = w[i1][j1];
// if(j1 >= 1 && j1 <= k && j2 >= 1 && j2 <= k){
if(i1 != i2) t += w[i2][j2];
x = max(x,f[k - 1][i1-1][i2] + t);//相当于从1 1这个矩阵格子往上和左,以及左上,以及自身来进行选择。
x = max(x,f[k - 1][i1-1][i2-1] + t);
x = max(x,f[k - 1][i1][i2] + t);
x = max(x,f[k - 1][i1][i2 - 1] + t);
// }
}
}
}
printf("%d\n",f[m + n][n][n]);
return 0;
}
方法② 将k的上限设为m+n;i1和i2的上限设为n; j1和j2的上限设为m。(m为列数)
AC代码如下
#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 10;
int f[N][N][N];
int n,r,c,v,m;
int w[N][N];
int main(){
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++){
for(int j =1; j <= m; j ++){
scanf("%d",&w[i][j]);
}
}
for(int k = 2; k <= m + n; k++){
for(int i1 = 1; i1 <= n; i1++){//当i1小于等于k时,if(j1<=k..)时,也能过。
for(int i2 = 1; i2 <= n; i2++){
int j1 = k - i1, j2 = k - i2;
int &x = f[k][i1][i2];
int t = w[i1][j1];
if(j1 >= 1 && j1 <= m && j2 >= 1 && j2 <= m){
if(i1 != i2) t += w[i2][j2];
x = max(x,f[k - 1][i1-1][i2] + t);//相当于从1 1这个矩阵格子往上和左,以及左上,以及自身来进行选择。
x = max(x,f[k - 1][i1-1][i2-1] + t);
x = max(x,f[k - 1][i1][i2] + t);
x = max(x,f[k - 1][i1][i2 - 1] + t);
}
}
}
}
printf("%d\n",f[m + n][n][n]);
return 0;
}