一开始不知道怎么解决后效性,以为自己记录状态的方式错了,实际上是转移方程想错了
学习了:如果怎么dp都发觉有后效性,一定是dp的姿势不对
dp[i][j] 如果采用向左的决策,要从dp[i-1][j] 转移过来,
如果采用向上的决策,要从dp[i][j-1]转移过来,
这样前面的方程里怎么决策才不会对后来那个方程有影响
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include <set>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define N 505
int r,c;
int west[N][N],nor[N][N];
int dp[N][N];
int main ()
{
while(scanf("%d%d",&r,&c)!=EOF)
{
if(r==0 && c==0) break;
for(int i=1;i<=r;++i)
for(int j=1;j<=c;++j)
scanf("%d",&west[i][j]);
for(int i=1;i<=r;++i)
for(int j=1;j<=c;++j)
scanf("%d",&nor[i][j]);
for(int i=1;i<=r;++i)
for(int j=2;j<=c;++j)
west[i][j]+=west[i][j-1];
for(int j=1;j<=c;++j)
for(int i=2;i<=r;++i)
nor[i][j]+=nor[i-1][j];
memset(dp,0,sizeof(dp));
for(int i=0;i<=r;++i)
for(int j=0;j<=c;++j)
{
dp[i][j+1]=max(dp[i][j+1],dp[i][j]+nor[i][j+1]);
dp[i+1][j]=max(dp[i+1][j],dp[i][j]+west[i+1][j]);
}
printf("%d\n",dp[r][c]);
}
return 0;
}