小白兔拔萝卜递推求解

#include<stdlib.h>
#include<stdio.h>
#include <time.h>

const int M = 8;  // 萝卜地行数
const int N = 10; // 萝卜地列数
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[0][0] = v[0][0];  // 入口处的最优萝卜数就是本身的萝卜数
            } else if (i == 0 && j!= 0) {
                c[0][j] = c[0][j - 1] + v[0][j];  // 最上面一行,只能从左边位置过来,累加萝卜数
            } else if (i!= 0 && j == 0) {
                c[i][0] = c[i - 1][0] + v[i][0];  // 最左侧一列,只能从上边位置过来,累加萝卜数
            } else {
                // 其他部分,选择从左边或者上边过来能获取更多萝卜的路径,加上当前位置萝卜数
                c[i][j] = (c[i - 1][j] > c[i][j - 1]? c[i - 1][j] : c[i][j - 1]) + v[i][j];
            }
        }
    }
    return c[m][n];  // 返回最优萝卜矩阵右下角的值
}

// 反向寻找最优萝卜矩阵中最优解的来源,标记路径
void xunlu(int m, int n) {
    int i = m, j = n;
    int path[M + N][2];  // 用于存储路径坐标,最多可能走过M+N个位置
    int index = 0;
    while (i > 0 || j > 0) {
        path[index][0] = i;
        path[index][1] = j;
        if (i == 0) {
            j--;  // 如果在第一行,只能从左往右走
        } else if (j == 0) {
            i--;  // 如果在第一列,只能从上往下走
        } else {
            // 比较上边和左边位置的最优值,选择来源路径
            if (c[i - 1][j] > c[i][j - 1]) {
                i--;
            } else {
                j--;
            }
        }
        index++;
    }
    path[index][0] = 0;
    path[index][1] = 0;  // 起点坐标

    // 倒序输出路径坐标,展示走过的路径
    printf("最优路径如下(坐标从右下角开始反向追溯到左上角):\n");
    for (int k = index; k >= 0; k--) {
        printf("(%d, %d) ", path[k][0], path[k][1]);
    }
    printf("\n");
}

int main() {
    int i, j, count;
    printf("一片萝卜地如下:\n");
    srand((unsigned int)time(NULL));  // 初始化随机数种子
    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 = dituiluobo(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");
    }
    xunlu(M - 1, N - 1);
    return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值