问题:小白兔从一片田地的左上角进入,右下角离开,田地中每个方格里有数量不等的萝卜供小白兔拿,小白兔每次只能往右或者往下走,求当小白兔从右下角离开时,能够获得的最多萝卜数,且说出其的路径。
起点
终点
采用动态规划法,让小白兔走入田地矩阵(v【】【】),即从左上角开始,将紧邻的上方和左方的数进行比较,取其中加大的数与本格代表的数相加作为萝卜总数写入对应的萝卜矩阵(c【】【】)中,如果上方或左方没有数则不参与运算。依此类推可以在萝卜矩阵的右下方得到本体的最优解。
#include<stdlib.h>
#include<stdio.h>
#include <time.h>
const int M=5;//萝卜地行数
const int N=5;//萝卜地列数
int v[M][N],c[M][N];//萝卜数矩阵,最优萝卜数矩阵
int diguiluobo(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];
}
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,count;
printf("一片萝卜地如下:\n");
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
v[i][j]=rand()%10;
c[i][j]=0;
printf("%d ",v[i][j]);
}
printf("\n");
}
count=diguiluobo(M-1,N-1);
printf("递归小萝卜结果为%d\n",count);
printf("最优萝卜矩阵如下:\n");
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
printf("%d ",c[i][j]);
}
printf("\n");
}
printf("最优追踪解如下:\n");
xunlu(M-1,N-1);
return 0;
}