递推DP UVA 1366 Martian Mining

题目传送门

 1 /*
 2     题意:抽象一点就是给两个矩阵,重叠的(就是两者选择其一),两种铺路:从右到左和从下到上,中途不能转弯,
 3         到达边界后把沿途路上的权值相加求和使最大
 4     DP:这是道递推题,首先我题目看了老半天,看懂后写出前缀和又不知道该如何定义状态好,写不出状态转移方程,太弱了。
 5          dp[i][j]表示以(i, j)为右下角时求得的最大值,状态转移方程:dp[i][j] = max (dp[i-1][j] + sum1[i][j], dp[i][j-1] + sum2[i][j]);   sum1表示列的前缀,sum2表示行的前缀
 6 */
 7 /************************************************
 8 * Author        :Running_Time
 9 * Created Time  :2015-8-9 10:18:37
10 * File Name     :UVA_1366.cpp
11  ************************************************/
12
13 #include <cstdio>
14 #include <algorithm>
15 #include <iostream>
16 #include <sstream>
17 #include <cstring>
18 #include <cmath>
19 #include <string>
20 #include <vector>
21 #include <queue>
22 #include <deque>
23 #include <stack>
24 #include <list>
25 #include <map>
26 #include <set>
27 #include <bitset>
28 #include <cstdlib>
29 #include <ctime>
30 using namespace std;
31
32 #define lson l, mid, rt << 1
33 #define rson mid + 1, r, rt << 1 | 1
34 typedef long long ll;
35 const int MAXN = 5e2 + 10;
36 const int INF = 0x3f3f3f3f;
37 const int MOD = 1e9 + 7;
38 int a[MAXN][MAXN], b[MAXN][MAXN];
39 int sum1[MAXN][MAXN], sum2[MAXN][MAXN];
40 int dp[MAXN][MAXN];
41
42 int main(void)    {     //UVA 1366 Martian Mining
43     int n, m;
44     while (scanf ("%d%d", &n, &m) == 2) {
45         if (!n && !m)   break;
46         memset (sum1, 0, sizeof (sum1));
47         for (int i=1; i<=n; ++i)    {
48             for (int j=1; j<=m; ++j)    {
49                 scanf ("%d", &a[i][j]); sum1[i][j] = sum1[i][j-1] + a[i][j];
50             }
51         }
52         memset (sum2, 0, sizeof (sum2));
53         for (int i=1; i<=n; ++i)    {
54             for (int j=1; j<=m; ++j)    {
55                 scanf ("%d", &b[i][j]); sum2[i][j] = sum2[i-1][j] + b[i][j];
56             }
57         }
58         memset (dp, 0, sizeof (dp));
59         for (int i=1; i<=n; ++i)    {
60             for (int j=1; j<=m; ++j)    {
61                 dp[i][j] = max (dp[i-1][j] + sum1[i][j], dp[i][j-1] + sum2[i][j]);
62             }
63         }
64         printf ("%d\n", dp[n][m]);
65     }
66
67     return 0;
68 }
时间: 2024-08-10 23:04:24

递推DP UVA 1366 Martian Mining的相关文章

递推DP UVA 607 Scheduling Lectures

题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按照时间多少,学生会有不满意度.问最少要几节课讲完主题,如果多种方案输出不满意度最小的 分析:dp[i]表示前i个主题最少要多少节课讲完,那么这个主题可能和上个主题在同一节课讲或者多开新的一节课讲,状态转移方程:看代码:优先满足节数少的情况 收获:普通的递推DP 代码: /**************

UVA - 1366 Martian Mining 三维dp

题目大意:在一个n * m的格子上有两种矿物.A矿只能从右往左运输,B矿只能从下往上运输,现在要求你在这格子上铺设管道(管道不能中断或者拐弯),用管道来运输A矿和B矿,使得运输的A矿和B矿的和最大 解题思路:设dp[i][j][0]为以(i,j)为矩阵的右下角,铺设从右往左的管道所能运输的最大值,那么第i行的第1列到第j列只能铺设从右往左的管道,所以dp[i][j][0] = max(dp[i-1][j][0],dp[i-1][j][1]) + A[i][j] 设dp[i][j][1]为以(i,

递推DP UVA 1291 Dance Dance Revolution

题目传送门 1 /* 2 题意:给一串跳舞的动作,至少一只脚落到指定的位置,不同的走法有不同的体力消耗,问最小体力消费多少 3 DP:dp[i][j][k] 表示前i个动作,当前状态(j, k)的最小消费,状态转移方程:(a[i], k) <- min (a[i-1], k) + cost 4 以及(a[i-1], a[i]) <- min (a[i-1], k) + cost, (k, a[i])和(a[i], a[i-1])情况类似,最后再去最小值就行了 5 */ 6 /*********

递推DP UVA 1424 Salesmen

题目传送门 1 /* 2 题意:给定包含n个点的无向图和一个长度为L的序列,修改尽量少的点使得相邻的数字相同或连通 3 DP:状态转移方程:dp[i][j] = min (dp[i][j], dp[i-1][k] + (j != a[i])); 4 dp[i][j]表示前i个数字以j结尾的最小花费.我自己写了很长时间,很复杂,状态转移的不好. 5 应该能知道前一个状态的所有情况,每一维数组记录的就是一个状态 6 */ 7 /************************************

递推DP UVA 590 Always on the run

题目传送门 题意:题意难懂,就是一个小偷在m天内从城市1飞到城市n最小花费,输入的是每个城市飞到其他城市的航班. 分析:dp[i][j] 表示小偷第i天在城市j的最小花费.状态转移方程:dp[i][j] = min (dp[i-1][k] + cost[k][j][t%day]) t表示在t天时k飞往j的飞机的花费 收获: 代码: /************************************************ * Author :Running_Time * Created

hdu 1284 钱币兑换问题 (递推 || DP || 母函数)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5069    Accepted Submission(s): 2868 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outpu

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs