• POJ2948 Martian Mining 动态规划


    详见代码:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    int N, M, dp[505][505];
    int row[505][505], col[505][505];
    
    /*
    题意:给定一个矩阵,矩阵中的每一个点都有两种矿产,A矿产只能够运送到上面去,B矿产只能
         够运送到左边去,现在要在每个点都设置一个传送带传送带共有两种,一种是往上,一种
         是往左,每个格子只能够做一个选择,问如何安排这些传送带使得整个的传输带上能够运
         抵目的地的矿产最多.
         
    解法:这题拥有这样一个性质.由于每当一个点被选取后,如果这个点是选择往上走的话,那么
         这个点的这一列上面的点就一定会全部选取,如果这个点是往左走的话,那么该点的左
         边同一行的点也应该计算在内
         设 dp[i][j]表示子矩阵(1, 1) 到 (i, j)的最大传输值,那么有动态规划方程:
         dp[i][j] = max(col[i][j]+dp[i][j-1], row[i][j]+dp[i-1][j])
         其中col[i][j]表示第j列从第1行到第i行的和; row[i][j]表示第i行1到j列的和
         该方程说明了一个事实就是对于当前点是否选择是影响整个这一行或者是这一列的
         除此之外,对其他地方并无影响 
    */
    
    int DP() {
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= M; ++j) {
                dp[i][j] = max(col[i][j]+dp[i][j-1], row[i][j]+dp[i-1][j]);
            }
        }
        return dp[N][M];
    }
    
    int main() {
        while (scanf("%d %d", &N, &M), N|M) {
            for (int i = 1; i <= N; ++i) {
                for (int j = 1; j <= M; ++j) { // 该矩阵中的矿产需要运送到左边去
                    scanf("%d", &row[i][j]);
                    row[i][j] += row[i][j-1];
                }
            }
            for (int i = 1; i <= N; ++i) {
                for (int j = 1; j <= N; ++j) {
                    scanf("%d", &col[i][j]);
                    col[i][j] += col[i-1][j];
                }
            }
            printf("%d\n", DP());
        }
        return 0;    
    }
  • 相关阅读:
    VisualStudio2010配置OpenCV的一种一劳永逸的方法
    QT5 Failed to load platform plugin &quot;windows&quot; 终极解决方式 命令行问题
    轻松学习JavaScript二十二:DOM编程学习之节点操作
    Eclipse中安装TestNG插件
    Java Timer 定时器的使用
    技术开发团队的项目管理工具
    python里一个class可以定义多个构造函数
    python中的多继承
    python基础之使用os.system来执行系统命令
    python下划线变量的含义
  • 原文地址:https://www.cnblogs.com/Lyush/p/2860271.html
Copyright © 2020-2023  润新知