0
点赞
收藏
分享

微信扫一扫

HDU2571_命运

吴陆奇 2022-07-27 阅读 99


命运







Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Total Submission(s): 9998    Accepted Submission(s): 3523



Problem Description


穿过幽谷意味着离大魔王lemon已经无限接近了!

可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机关。要知道,不论何人,若在迷宫中被困1小时以上,则必死无疑!

可怜的yifenfei为了去救MM,义无返顾地跳进了迷宫。让我们一起帮帮执着的他吧!


命运大迷宫可以看成是一个两维的方格阵列,

下图所示: 

HDU2571_命运_#include


yifenfei一开始在左上角,目的当然是到达右下角的大魔王所在地。迷宫的每一个格子都受到幸运女神眷恋或者痛苦魔王的诅咒,所以每个格子都对应一个值,走到那里便自动得到了对应的值。

现在规定yifenfei只能向右或者向下走,向下一次只能走一格。但是如果向右走,则每次可以走一格或者走到该行的列数是当前所在列数倍数的格子,即:如果当前格子是(x,y),下一步可以是(x+1,y),(x,y+1)或者(x,y*k) 其中k>1。 


为了能够最大把握的消灭魔王lemon,yifenfei希望能够在这个命运大迷宫中得到最大的幸运值。

HDU2571_命运_#include_02


题目大意:给你一个M*N的区域,只能向右走或是向下走。向下只能走一步,

向右能够走一步或者走当前列数的倍数次(最小为2倍),问走到右下角,总和

最大是多少

思路:动态规划思想。每一点dp[i][j]的值都为向上一步dp[i-1][j]或是向左一步

dp[i][j-1]得到最大和中的较大值,再比较它本身与它的1/2、1/3…倍(前提是

1/2、1/3…倍为整数)比较,取较大值,最后加上本身就是当前最优的情况。

递推到dp[N][M],得到结果。


<span style="font-family:Microsoft YaHei;font-size:18px;">#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int INF = 0xffffff0;
int map[21][1010], dp[21][1010];
int main()
{
int C, N, M;
scanf("%d", &C);

while(C--)
{
scanf("%d%d", &N, &M);
memset(map, 0, sizeof(map));
memset(dp, 0, sizeof(dp));

for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= M; j++)
{
scanf("%d", &map[i][j]);
}
}

for(int i = 0; i <= N; i++)
{
dp[i][0] = -INF;
}

for(int j = 0; j <= M; j++)
{
dp[0][j] = -INF;
}

dp[0][1] = dp[1][0] = 0;

for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= M; j++)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

for(int k = 2; k <= M; k++)
{
if(j % k == 0)
{
dp[i][j] = max(dp[i][j], dp[i][j / k]);
}
}

dp[i][j] += map[i][j];
}
}

printf("%d\n", dp[N][M]);
}

return 0;
}
/*
错误:
for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= M; j++)
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + map[i][j];
for(int k = 2; k <= M; k++)
{
if(j%k==0)
dp[i][j] = max(dp[i][j],dp[i][j/k]);
}
}
}
*/
</span>




举报

相关推荐

0 条评论