题意:给出一个矩阵,要求从1,1走到n,m,每个格子里都有一定的幸运值,每次只能向下或向右走,如果当前格子是(x,y),下一步可以是(x+1,y),(x,y+1)或者(x,y*k) 其中k>1。
求走到n,m能得到的最大幸运值.
算一道简单的dp题吧.
设dp[i][j]为走到i,j位置能得到的最大值.
那么dp[i][j]=max(dp[i][j - 1], dp[i - 1][j], max{dp[i][k] k满足 k | j 也就是整除j}).
初始化dp为负无穷.
dp[1][1]为val[1][1].
#include <cstdio>
#include <memory.h>
#include <iostream>
using namespace std;
const int MAX = 1001;
int dp[21][MAX], path[21][MAX];
int l_val[21][MAX];
int main(int argc, char const *argv[]){
int C;
scanf("%d", &C);
while(C--){
int n, m;
scanf("%d%d", &n, &m);
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
scanf("%d", &l_val[i][j]);
dp[i][j] = -100000000;
}
}
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
int maxv;
if(i == 1){
if(j == 1) maxv = 0;
else maxv = dp[i][j - 1];
}else{
if(j == 1)maxv = dp[i - 1][j];
else maxv = max(dp[i - 1][j], dp[i][j - 1]);
}
for(int k = 1; k * k <= j; ++k){
if(j % k == 0){
int v = j / k;
if(v != j)maxv = max(maxv, dp[i][v]);
if(k != j)maxv = max(maxv, dp[i][k]);
}
}
dp[i][j] = maxv + l_val[i][j];
}
}
printf("%d\n", dp[n][m]);
}
return 0;
}