0 进入 | 3 | 2 | 1 | 3 | 4 |
5 | 4 | 3 | 2 | 3 | 4 |
2 | 0 | 4 | 5 | 3 | 2 |
4 | 5 | 3 | 2 | 1 | 2 |
4 | 2 | 3 | 4 | 5 | 3 |
2 | 2 | 2 | 3 | 4 | 0 离开 |
小白兔从一片田地的左上角进入,右下角离开,田地中每个方格里有数量不等的萝卜供小白兔拿取,小白兔必须尽快离开田地以降低被猎人发现的概率(即小白兔每次必须选择向下或者向右走一格,并拿走格子里的萝卜),在保证尽可能安全的前提下,请为小白兔规划一条最佳的拿萝卜路径。
任务1-1:打开任务1.cpp,在函数diguiluobo中依照动态规划方程使用递归实现小白兔拔萝卜问题的动态规划求解。
任务1-2:比较小白兔拔萝卜问题的递归和递推求解执行时间,思考解决方法。
任务1-3:在函数jizhuluobo中利用备忘录方法在递归过程中记录并检查各个子问题的解,使递归方法达到和递推方法类似的求解效率。
(2)爬楼梯问题的备忘录求解
任务2:爬楼梯问题和斐波那契数列的计算极其相似,请在任务2.cpp中编写程序,利用备忘录的方法使递归程序达到和递推程序类似的求解效率。
任务3:如果爬楼梯问题允许一次最多上3个台阶,应该如何编写程序求解?
#include
#include
#include
const int M=15;//萝卜地行数
const int N=15;//萝卜地列数
int v[M][N],c[M][N];//萝卜数,最优萝卜数
int dituiluobo(int m,int n)
{
//递推求解拔萝卜问题
for(int i=0;i<=m;i++)
for(int j=0;j<=n;j++)
{
if(i==0&&j==0) c[i][j]=v[i][j];
if(i==0&&j!=0) c[i][j]=c[i][j-1]+v[i][j];
if(i!=0&&j==0) c[i][j]=c[i-1][j]+v[i][j];
if(i!=0&&j!=0)
if(c[i][j-1]>c[i-1][j]) c[i][j]=c[i][j-1]+v[i][j];
else c[i][j]=c[i-1][j]+v[i][j];
}
return c[m][n];
}
int diguiluobo(int m,int n)
{
//递归求解拔萝卜问题
if(m==0&&n==0) return v[m][n];
if(m==0&&n!=0) return diguiluobo(m,n-1)+v[m][n];
if(m!=0&&n==0) return diguiluobo(m-1,n)+v[m][n];
if(m!=0&&n!=0) {
int a=diguiluobo(m,n-1);
int b=diguiluobo(m-1,n);
if(a>b)
return a+v[m][n];
else
return b+v[m][n];
}
}
int jizhuluobo(int m,int n)
{
//备忘录优化递归求解
return 0;
}
void xunlu(int m,int n)
{
printf("%d,%d\n",m,n);
while(m!=0||n!=0)
if(m==0){
n--;
printf("%d,%d\n",m,n);}
else if(n==0){
m--;
printf("%d,%d\n",m,n);}
else if(c[m-1][n]>c[m][n-1]){
m--;
printf("%d,%d\n",m,n);}
else{
n--;
printf("%d,%d\n",m,n);}
}
int main()
{
int i,j,start,end,t,count;
printf("一片萝卜地如下:\n");
for(i=0;i {
for(j=0;j {
v[i][j]=rand()%10;
c[i][j]=0;
printf("%d ",v[i][j]);
}
printf("\n");
}
start=clock();
count=diguiluobo(M-1,N-1);
end=clock();
t=end-start;
printf("递归小萝卜结果为%d,耗费时间:%dms\n",count,t);
start=clock();
count=jizhuluobo(M-1,N-1);
end=clock();
t=end-start;
printf("记住小萝卜结果为%d,耗费时间:%dms\n",count,t);
start=clock();
count=dituiluobo(M-1,N-1);
end=clock();
t=end-start;
printf("递推小萝卜结果为%d,耗费时间:%dms\n",count,t);
printf("萝卜矩阵如下:\n");
for(i=0;i {
for(j=0;j {
printf("%d ",c[i][j]);
}
printf("\n");
}
xunlu(M-1,N-1);
return 0;
}