题意易懂,原来是利用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 ",i, j, sum[i][j]); } } printf("%d ", 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 ", dp[1]); } } return 0; }