Problem H ID:1008
简单题意:一个两维的方格阵列,从左上角走到右下角,每个格子里都有一个数字K ( |K|<100 ),每一步(从(x,y)走)有三种走法:向下走一个格(x+1,y)、向右走一个格(x,y+1)或者(x,y*k) ,k为大于等于2的整数,走过的数字将累加。问:到达右下角时最大值为多少?
解题思路形成过程:一个比较简答的dp题,先列遍历,再对每一行遍历,每一个格的最大值为当前格子原有的值加上所有的可能的上一步的最大值。 注意格子里值的范围,有可能为负数。
感想:WA了一次,没有考虑到格子里的值为负数的情况。总体来说比较简单。
代码:#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int c,n,m;
int dp[21][1001];
int cmax(int _i,int _j)
{
int _cmax=dp[_i][_j-1];
for(int i=2;i<=_j;++i)
if(_j%i==0)
if(dp[_i][_j/i]>_cmax)
_cmax=dp[_i][_j/i];
if(dp[_i-1][_j]>_cmax)
_cmax=dp[_i-1][_j];
return _cmax;
}
int main()
{
//freopen("1.txt","r",stdin);
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=m;++i)
dp[0][i]=-9999999;
for(int i=0;i<=n;++i)
dp[i][0]=-9999999;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
scanf("%d",&dp[i][j]);
if(!(i==1&&j==1))
dp[i][j]+=cmax(i,j);
}
printf("%d\n",dp[n][m]);
}
return 0;
}
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int c,n,m;
int dp[21][1001];
int cmax(int _i,int _j)
{
int _cmax=dp[_i][_j-1];
for(int i=2;i<=_j;++i)
if(_j%i==0)
if(dp[_i][_j/i]>_cmax)
_cmax=dp[_i][_j/i];
if(dp[_i-1][_j]>_cmax)
_cmax=dp[_i-1][_j];
return _cmax;
}
int main()
{
//freopen("1.txt","r",stdin);
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=m;++i)
dp[0][i]=-9999999;
for(int i=0;i<=n;++i)
dp[i][0]=-9999999;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
scanf("%d",&dp[i][j]);
if(!(i==1&&j==1))
dp[i][j]+=cmax(i,j);
}
printf("%d\n",dp[n][m]);
}
return 0;
}