简单题意:
在二维空间中,选择一条幸运值最大的路,每次的走法只能 向前走一步,或者向下走一步,或者向前走当前列数的 k 倍的列数位置(行都是当前行,k>1),求出达到右下角那点时所能得到的最大幸运值。
解题思路:
每个单元存此位置到右下角的最大值,先算出最后一行(因为最后一行只可以向右走)和最后一列(只可以向下走),然后从魔王的左上角那个位置开始逐个填表,对于这些位置,能走的路线是往下一步,或者往右一步,或者往右k倍步,取这三种方案的最大值再加上它本身的值来更新。最后输出1行1列的值就行。
代码如下;
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main()
{
int k, m, n, temp;
cin >> k;
int opt[1002];
while (k--)
{
memset(opt, 0, sizeof(opt));
cin >> m >> n;
cin >> opt[1];
for (int j = 2; j <= n; j++)
{
cin >> temp;
for (int k = 1; k <= j / 2; k++)
{
if (j % k == 0)
{
if (opt[j] ==0 || opt[j] < opt[k] + temp)
opt[j] = opt[k] + temp;
}
}
if ((j > 2 && opt[j] < opt[j - 1] + temp) || opt[j] ==0)
opt[j] = opt[j - 1] + temp;
}
for (int i = 1; i < m; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> temp;
int t = opt[j];
for (int k = 1; k <= j / 2; k++)
{
if (j % k == 0)
{
if ( opt[k] > t)
t = opt[k];
}
}
if (j > 2 && opt[j - 1] > t)
t = opt[j - 1] ;
opt[j] = t + temp;
}
}
cout << opt[n] << endl;
}
return 0;
}
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main()
{
int k, m, n, temp;
cin >> k;
int opt[1002];
while (k--)
{
memset(opt, 0, sizeof(opt));
cin >> m >> n;
cin >> opt[1];
for (int j = 2; j <= n; j++)
{
cin >> temp;
for (int k = 1; k <= j / 2; k++)
{
if (j % k == 0)
{
if (opt[j] ==0 || opt[j] < opt[k] + temp)
opt[j] = opt[k] + temp;
}
}
if ((j > 2 && opt[j] < opt[j - 1] + temp) || opt[j] ==0)
opt[j] = opt[j - 1] + temp;
}
for (int i = 1; i < m; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> temp;
int t = opt[j];
for (int k = 1; k <= j / 2; k++)
{
if (j % k == 0)
{
if ( opt[k] > t)
t = opt[k];
}
}
if (j > 2 && opt[j - 1] > t)
t = opt[j - 1] ;
opt[j] = t + temp;
}
}
cout << opt[n] << endl;
}
return 0;
}