题意:有一个表格,每个表格上有数字,经过该格子会获得格子上的数字,从左上角出发,每一次移动可以走到下一列,下一行,或者移动到列数为当前列的整数倍的列上,问到达右下角是数字和最大为多少。
简单的DP题,状态转移方程也很简单,按题意来就可以了dp[i][j]=max(max(dp[i-1][j],dp[i][j-1]),dp[i][j/k])+arr[i][j]
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1020;
int dp[N][N];
int arr[N][N];
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
memset(dp,0,sizeof(dp));
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> arr[i][j];
dp[i][j] = arr[i][j];
}
}
for (int i = 2; i <= m; i++) {
dp[0][i] = -inf;
}
for (int i = 2; i <= n; i++) {
dp[i][0] = -inf;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
for (int k = 2; k<=j; k++) {
if (j % k == 0) {
dp[i][j] = max(dp[i][j], dp[i][j / k]);
}
}
dp[i][j] += arr[i][j];
}
}
cout << dp[n][m]<<endl;
}
}