题意易懂,原来是利用BFS队列,发现居然WA了,就看了一下别人的思路,思路很简单⊙﹏⊙b汗;
每一个点,都能从规定的方向走到该点,我们就选择能走到该点的最大的那个加,
sum [i][j] =max( max(sum[i][j - 1], sum[i -1][j]), sum[i][能被j整除的]] i>2,j>2
代码
#include "stdio.h"
#include "iostream"
using namespace std;
int main()
{
//freopen("1.in","r",stdin);
int t;
cin >> t;
while(t--)
{
int n, m, i, j, a[25][1005];
cin >> n >> m;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin >> a[i][j];
}
}
int sum[25][1005];
sum[1][1] = a[1][1];
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(i==1&& j==1) continue;
if(j == 1 && i > 1) //第一列,这种情况下,能走到这个点的只有一个点,下面的就不用执行了
{
sum[i][j] = sum[i-1][j];
sum[i][j] += a[i][j];
continue;
}
if(i == 1 && j > 1) // 第一行 的情况
{
sum[i][j] = sum[i][j-1];
}
if(i>1 && j>1) //不是第一行,也不是第一列的情况
{
sum[i][j] = max(sum[i-1][j],sum[i][j-1]);
}
for(int k=2;j/k>=1;k++)
{
int x = j/k;
if(x*k == j)
sum[i][j] = max(sum[i][j], sum[i][x]);
}
sum[i][j] += a[i][j];
//printf("sum[%d][%d] = %d\n",i, j, sum[i][j]);
}
}
printf("%d\n", sum[n][m]);
}
}
大神 15MS AC代码
#include <iostream>
#include <cstdio>
using namespace std;
short a[21][1001];
int dp[1001];
int main()
{
//freopen("1.in", "r", stdin);
int C, n, m, i, j, t;
scanf("%d", &C);
while (C--)
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
{
scanf("%hd", &a[i][j]);
}
for (i = n; i >= 1; --i)
{
for (j = m; j >= 1; --j)
{
if (i == n)
{
if (j == m)
{
dp[j] = a[i][j];
continue;
}
else
{
dp[j] = dp[j + 1];
}
}
else
{
if (j == m)
{
dp[j] = dp[j] + a[i][j];
continue;
}
else
if (dp[j + 1] > dp[j])
{
dp[j] = dp[j + 1];
}
}
t = j * 2;
while (t <= m)
{
if (dp[j] < dp[t])
{
dp[j] = dp[t];
}
t += j;
}
dp[j] += a[i][j];
}
}
printf("%d\n", dp[1]);
}
}
return 0;
}