我在编程论坛上发现了这个问题:
给出了一个由 N*M 个单元组成的表格,每个单元有一定数量的苹果。你从左上角开始。在每个步骤中,您可以向下或向右移动一个单元格。如果您从左上角移动到右下角,请设计一种算法来找到您可以收集的最大苹果数。
我想到了三种不同的复杂性[在时间和空间方面]:
方法1[最快]:
for(j=1,i=0;j<column;j++)
apple[i][j]=apple[i][j-1]+apple[i][j];
for(i=1,j=0;i<row;i++)
apple[i][j]=apple[i-1][j]+apple[i][j];
for(i=1;i<row;i++)
{
for(j=1;j<column;j++)
{
if(apple[i][j-1]>=apple[i-1][j])
apple[i][j]=apple[i][j]+apple[i][j-1];
else
apple[i][j]=apple[i][j]+apple[i-1][j];
}
}
printf("\n maximum apple u can pick=%d",apple[row-1][column-1]);
方法二:
结果是所有插槽最初为 0 的临时数组。
int getMax(int i, int j)
{
if( (i<ROW) && (j<COL) )
{
if( result[i][j] != 0 )
return result[i][j];
else
{
int right = getMax(i, j+1);
int down = getMax(i+1, j);
result[i][j] = ( (right>down) ? right : down )+apples[i][j];
return result[i][j];
}
}
else
return 0;
}
方法3[使用最少的空间]:
它不使用任何临时数组。
int getMax(int i, int j)
{
if( (i<M) && (j<N) )
{
int right = getMax(i, j+1);
int down = getMax(i+1, j);
return apples[i][j]+(right>down?right:down);
}
else
return 0;
}
我想知道解决这个问题的最佳方法是什么?