分析:題目意思就是不能有任何兩個數在相鄰的行和相鄰的列中,先對某一行分析,如果先取了第1個數,則接下來可以取第3或4個數(因為求所有取的數之和最大,所以不可能一下跳過3個以上),如果先取第2個數,接下來可以取第4或5個數,依此類推......
從這裡可以觀察到,當取到第4個數時,所有取出數的和的大小取決於第1個數和第2個數的大小,意思就是當取到第i個數時,和的大小取決於取到第i-3個數和取到第i-2時和的大小,即c[i]=c[i]+max(c[i-2],c[i-3]);那麼對於每一列也同樣考慮,可以得到r[i]=r[i]+max(r[i-2],r[i-3]).
[cpp]
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int r[2000001], c[2000001];
int main(){
int n,m;
while (~scanf("%d%d",&n,&m)) {
r[0]=0;c[0]=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++)
scanf("%d",&c[j]);
for(int j=3;j<=m; j++)
c[j]+=max(c[j-2],c[j-3]);
r[i]=max(c[m-1],c[m]);
if(i>=3)r[i]+=max(r[i-2],r[i-3]);
}
printf("%d\n", max(r[n],r[n-1]));
}
return 0;
}
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int r[2000001], c[2000001];
int main(){
int n,m;
while (~scanf("%d%d",&n,&m)) {
r[0]=0;c[0]=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++)
scanf("%d",&c[j]);
for(int j=3;j<=m; j++)
c[j]+=max(c[j-2],c[j-3]);
r[i]=max(c[m-1],c[m]);
if(i>=3)r[i]+=max(r[i-2],r[i-3]);
}
printf("%d\n", max(r[n],r[n-1]));
}
return 0;
}