发现自己对动态规划还是不能了然于掌。大概的思想就是:假设知道上一次最佳的路线,计算这一次的。而上一次最佳的路线不一定就能算出这一次最佳的路线,因此需要对上一次所有的路线进行一个处理。
点击打开链接
动态规划的递推公式
p[i][j] = max(dp[i-1][j],dp[i][j-1],dp[i][k]) + data[i][j]。其中dp[i][j]表示男主角到达第i行第j列所能达到的幸运值的最大值。data[i][j]表示第i行第j列的幸运值。其中 k为j的真因子。(找真因子,包括1,即找除本身以外的其他约数,因为题目存在 "
每次可以走一格或者走到该行的列数是当前所在列数倍数的格子
" 这样的条件)
下面是代码:发现网上有一套代码写的不严谨,这个是改过的。
#include <iostream>
#include <iomanip>
#include<queue>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<string>
//定义函数段
#define repf(i,a,b) for(int i =(a);i<(b);i++)
using namespace std;
const int inf = -1000;
int data[21][1001];
int dp[21][1001];
int main() {
int num,r,c,Max ;
cin>>num;
while(num--){
cin >> r >> c ;
for(int i = 1 ; i <=r;i++)
{
for(int j = 1 ;j <= c ; j++)
{
cin>>data[i][j];
}
}
memset(dp,0,sizeof(dp));
for(int i = 1 ; i <= r ; i ++)
{
for(int j = 1 ; j <=c ; j ++)
{
if(i==1&&j==1)
{
dp[i][j]=data[i][j];
continue ;
}
Max = -1000;
for(int k = 1 ; k <j ;k++)
{
if(j%k==0)
{
Max=max(Max,dp[i][k]);
}
}
if(i-1>=1)
{
Max = max(Max,dp[i-1][j]);
}
if(j-1>=1)
{
Max = max(Max,dp[i][j-1]);
}
dp[i][j] = Max+data[i][j];
}
}
cout << dp[r][c] <<endl;
}
return 0;
}