解题思路:动态规划,从左上到右下
状态转移方程:
d[i][j] = max(d[i-1][j], d[i][j-1], d[i][k]) + a[i][j] (k<j && j%k == 0)
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define clr(p,v) memset(p,v,sizeof(p))
const int maxn = 1010 ;
int n, m, C;
int d[22][maxn];
int main()
{
scanf("%d", &C);
while (C--)
{
//Input
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j)
scanf("%d", &d[i][j]);
//Calculate
for (int i=1; i<=n; ++i)
{
for (int j=1; j<=m; ++j)
{
if (i == 1 && j == 1)
continue;
int mx;
if (i == 1)
mx = d[i][j-1];
else if (j == 1)
mx = d[i-1][j];
else
mx = max(d[i][j-1], d[i-1][j]);
//Calculate K time
for (int k=1, kmx=j>>1; k<=kmx; ++k) if (j%k == 0)
mx = max(mx, d[i][k]);
d[i][j] += mx;
}
}
//output
printf("%d\n", d[n][m]);
}
return 0;
}