题目:每次可以往下走一步,往右走一步,往右走到格子坐标的k倍,找到最佳的走法,使和最大;
所以每个格子(x,y)是由(x-1,y),或者(x,y-1),或者x相同,y0可以被y整除的格子走到的,每次选最大值就行了;
注意有负值;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[30][1010],dp[30][1010];
int fun(int x,int y){//这个位置横着所有可能的走法
int ans = dp[x][1];
for(int i = 2;i <= y/2;i++)
if(y%i==0) ans = max(ans,dp[x][i]);
return ans;
}
int main()
{
int t;
cin>>t;
while(t--){
memset(dp,0,sizeof(dp));
int n,m;
cin>>n>>m;
for(int i = 1;i <= n;i++){
dp[i][0] = -1e9;
for(int j = 1;j <= m;j++) cin>>a[i][j];
}
for(int j = 1;j <= m;j++) dp[0][j] = -1e9;
dp[1][0] = dp[0][1] = 0;//保证不影响结果
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
dp[i][j] = max(dp[i-1][j],max(dp[i][j-1],fun(i,j))) + a[i][j];
cout<<dp[n][m] << endl;
}
return 0;
}