第一次遇到这种背包问题,看网上的代码思路是四维数组,可是超时,然后又用三维数组优化
每步只可以右或往下走,所以状态转移就可以的到
状态转移方程
dp[i][ii][j][jj] = max( dp[i][ii-1][j][jj-1] , dp[i][ii-1][j-1][jj] , dp[i-1][ii][j][jj-1] ,
dp[i-1][ii][j-1][jj] ) + map[i][ii] + map[j][jj];
代码:
#include <iostream>
#include<string>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
int dp[100][100][100],M[55][55];
int main()
{
int t;
cin>>t;
while(t--)
{
int m,n;
cin>>m>>n;
memset(dp,0,sizeof(dp));
memset(M,0,sizeof(M));
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin>>M[i][j];
int all=m+n;
for(int k=2;k<=all;k++)
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
{
if(i!=j&&j<=k&&i<=k)//i,j不超过k,且不等于彼此可以保证不会走走过的路;
{
int s=max(dp[k-1][i-1][j],dp[k-1][i-1][j-1]);
int t=max(dp[k-1][i][j],dp[k-1][i][j-1]);
dp[k][i][j]=max(s,t)+M[i][k-i]+M[j][k-j];
}
}
int ans=Max(dp[all-1][m][m-1],dp[all-1][m-1][m]);
cout<<ans<<endl;
}
}