【DP】工业时代

Description

小FF的第一片矿区已经开始运作了, 他着手开展第二片矿区……小FF的第二片矿区, 也是"NewBe_One"计划的核
心部分, 因为在这片矿区里面有全宇宙最稀有的两种矿物,科学家称其为NEW矿和BE矿。矿区是被划分成一个n*m
的矩形区域。 小FF探明了每一小块区域里的NEW矿和BE矿的蕴藏量, 并且小FF还在矿区的北边和西边分别设置了N
EW矿和BE矿的收集站。你的任务是设计一个管道运输系统,使得运送的NEW矿和BE矿的总量最多。管道的型号有两
种,一种是东西向,一种是南北向。在一个格子内你能建造一种管道,但不能两种都建。如果两个同类型管道首位
相接,它们就可以被连接起来。另外这些矿物都十分不稳定,因此它们在运送过程中都不能拐弯。这就意味着如果
某个格子上建有南北向管道,但是它北边的格子建有东西向管道,那么这根南北向管道内运送的任何东西都将丢失
。进一步地,运到NEW矿收集站的BE矿也会丢失,运到BE矿收集站的NEW矿也会丢失。

Input

第一行包含两个整数n和m,表示矿区大小。
以下n行,每行m个整数,其中第i行第j个整数G[ i , j ] 描述各个格子上的BE矿数量。
接下来以类似的矩阵表示各个格子上的NEW矿数量。
0<= n, m <=1000;   
0<= G[ i, j ] <=1000.

Output

 仅一个整数, 表示最多可以采集到的NEW矿和BE矿的总量。

Sample Input

4 4
0 0 10 9
1 3 10 0
4 2 1 3
1 1 20 0
10 0 0 0
1 1 1 30
0 0 5 5
5 10 10 10

Sample Output

98

分析

此题考虑使用DP

首先,我们横向,纵向分别求前缀和

状态设计成三

dp[ i ][ j ][0]描述以( i, j )为右下角的矩阵范围内能采到的最多的BE矿

dp[ i ][ j ][1]描述以( i, j )为右下角的矩阵范围内能采到的最多的NEW矿

那么就可以很愉快地得到状态转移方程

dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1]) + a[i][j];
dp[i][j][1] = max(dp[i][j - 1][0], dp[i][j - 1][1]) + b[i][j];

这样一来最后的答案就是

max(dp[n][m][0], dp[n][m][1])

注意开long long

代码

#include<bits/stdc++.h>
using namespace std;
long long n, m;
long long a[1010][1010], b[1010][1010];
long long dp[1010][1010][4];

inline long long read() {
    long long x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
    return x * f;
}

int main() {
    n = read(), m = read();
    for (long long i = 1; i <= n; i++) {
	for (long long j = 1; j <= m; j++) {
	    a[i][j] = a[i][j - 1] + read();
	}
    }
    for (long long i = 1; i <= n; i++) {
	for (long long j = 1; j <= m; j++) {
	    b[i][j] = b[i - 1][j] + read();
	}
    }
    for (long long i = 1; i <= n; i++) {
        for (long long j = 1; j <= m; j++) {
	    dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1]) + a[i][j];
	    dp[i][j][1] = max(dp[i][j - 1][0], dp[i][j - 1][1]) + b[i][j];
	}
    }
    printf("%lld", max(dp[n][m][0], dp[n][m][1]));
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值