CodeForces 429B Working out 动态规划

Description

Summer is coming! It‘s time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and m columns. Let number a[i][j] represents the calories burned by performing workout at the cell of gym in thei-th line and the j-th column.

Iahub starts with workout located at line 1 and column 1. He needs to finish with workout a[n][m]. After finishing workout a[i][j], he can go to workout a[i + 1][j] or a[i][j + 1]. Similarly, Iahubina starts with workout a[n][1] and she needs to finish with workouta[1][m]. After finishing workout from cell a[i][j], she goes to either a[i][j + 1] or a[i - 1][j].

There is one additional condition for their training. They have to meet in exactly one cell of gym. At that cell, none of them will work out. They will talk about fast exponentiation (pretty odd small talk) and then both of them will move to the next workout.

If a workout was done by either Iahub or Iahubina, it counts as total gain. Please plan a workout for Iahub and Iahubina such as total gain to be as big as possible. Note, that Iahub and Iahubina can perform workouts with different speed, so the number of cells that they use to reach meet cell may differs.

Input

The first line of the input contains two integers n and m (3 ≤ n, m ≤ 1000). Each of the next n lines contains m integers: j-th number from i-th line denotes element a[i][j] (0 ≤ a[i][j] ≤ 105).

Output

The output contains a single number — the maximum total gain possible.

题目大意:两个人(假设为A,B),打算健身,有N行M列个房间,每个房间能消耗Map[i][j]的卡路里,A起点为(1,1)要达到(n,m)点,且每次只能向右走一步或向下走一步,B起点为(n,1),要达到(1,m),且每次只能向上走一步,或向右走一步。有要求A,B必须在某一个房间相遇一次,且A,B在该房间不再消耗卡路里,因为两人锻炼身体的速度不同,所以在相遇时经过的房间数亦可能不相同。问两人合计最多消耗多少卡路里。

题目思路:分别从四个角向对角打dp表,然后遍历各个点认为该点为相遇的房间,依据该点求四个dp式的和,并找出最大值,具体看代码。

#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1005

using namespace std;

long long dp1[MAX][MAX],dp2[MAX][MAX],dp3[MAX][MAX],dp4[MAX][MAX],ans;

int Map[MAX][MAX],n,m;

void Ans()
{
    memset(dp1,0,sizeof(dp1));
    memset(dp2,0,sizeof(dp2));
    memset(dp3,0,sizeof(dp3));
    memset(dp4,0,sizeof(dp4));
    int i,j;
    for(i=1; i<=n; i++)//dp1
    {
        for(j=1; j<=m; j++)
        {
            dp1[i][j]=Map[i][j]+max(dp1[i-1][j],dp1[i][j-1]);
        }
    }

    for(i=n; i>=1; i--)//dp2
    {
        for(j=m; j>=1; j--)
        {
            dp2[i][j]=Map[i][j]+max(dp2[i+1][j],dp2[i][j+1]);
        }
    }

    for(i=1; i<=n; i++)//dp3
    {
        for(j=m; j>=1; j--)
        {
            dp3[i][j]=Map[i][j]+max(dp3[i-1][j],dp3[i][j+1]);
        }
    }
    for(i=n; i>=1; i--)//dp4
    {
        for(j=1; j<=m; j++)
        {
            dp4[i][j]=Map[i][j]+max(dp4[i+1][j],dp4[i][j-1]);
        }
    }
}

int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        ans=0;
        for(i=1; i<=n; i++)
            for(j=1; j<=m; j++)
                scanf("%d",&Map[i][j]);
        Ans();
        for(i=2; i<n; i++)//因为只能相遇一次,如果在第1行,第n行,第1列,第m列相遇的话那么下一步两人将走入同一个房间或对方之前进入过的房间
        {
            for(j=2; j<m; j++)
            {
                ans = max(ans,dp1[i-1][j]+dp2[i+1][j]+dp3[i][j+1]+dp4[i][j-1]);//因为相遇的房间不计入卡路里,所以将该点的四个角的dp式相加
                ans = max(ans,dp1[i][j-1]+dp2[i][j+1]+dp3[i-1][j]+dp4[i+1][j]);
            }
        }

        printf("%lld\n",ans);
    }
    return 0;
}

时间: 2024-10-17 01:33:17

CodeForces 429B Working out 动态规划的相关文章

Codeforces 429B B. Working out

题目意思: 给n*m的矩阵,每个格子有个数,A从(1,1)出发只能向下或右走,终点为(n,m),B从(n,1)出发只能向上或右走,终点为(1,m).两个人的速度不一样,走到的格子可以获的该格子的数,两人相遇的格子上的数两个人都不能拿.求A和B能拿到的数的总和的最大值. n,m<=1000 解题思路: 先预处理出每个格子到四个角落格子的路径最大数值, 然后枚举两个人相遇的交点格子,枚举A.B的进来和出去方式,求最大值即可. 注意边界情况. #include<stdio.h> #includ

Codeforces 429B Working out bfs构造

题目链接:点击打开链接 题意:给定n*m的矩阵 有一个人a从左上角走到右下角,只能↓或→走 另一个人b从左下角走到右上角,只能↑或→走 使得2个人的路径有且仅有一个格子是相交的. 统计2个人的权值和(相交格子的权值和不计) 问最大的权值和是多少. 思路: 首先转换一下题意,也就是找一个格子与4个角落连不相交的线. 我们观察相交的那个格子,那个格子的上下左右必然对应着一个角落. (i,j)点,那么(i-1,j)必然对应左上角或右上角的其中一个角落. 这样(i,j)点的4个相邻格子各自对应一个角落(

CODEFORCES 429B 动态规划

http://codeforces.com/problemset/problem/429/B 可以参考这篇文章: http://blog.csdn.net/pure_lady/article/details/46764839 因为有断点,所以可以预处理四个顶点到任意点的距离最大值,通过拼接得到断点后的距离 然后就是枚举断点的情况,发现断点不可能在边缘,就可以开始写了 #include <iostream> #include <string> #include <cstring

Codeforces 830D Singer House - 动态规划

It is known that passages in Singer house are complex and intertwined. Let's define a Singer k-house as a graph built by the following process: take complete binary tree of height k and add edges from each vertex to all its successors, if they are no

Codeforces 834D The Bakery - 动态规划 - 线段树

Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredients and a wonder-oven which can bake several types of cakes, and opened the bakery. Soon the expenses started to overcome the income, so Slastyona decid

Codeforces 837D Round Subset - 动态规划 - 数论

Let's call the roundness of the number the number of zeros to which it ends. You have an array of n numbers. You need to choose a subset of exactly k numbers so that the roundness of the product of the selected numbers will be maximum possible. Input

Codeforces 1000G Two-Paths 树形动态规划 LCA

原文链接https://www.cnblogs.com/zhouzhendong/p/9246484.html 题目传送门 - Codeforces 1000G Two-Paths 题意 给定一棵有 $n(2\leq n\leq 3\times 10^5)$ 个节点的树,其中节点 $i$ 有权值 $a_i$,边 $e$ 有权值 $w_e$.$(1\leq a_i,w_e\leq 10^9)$ 现在给出 $q(1\leq q\leq 4\times 10^5)$ 组询问,每组询问给定两个数 $x,

CodeForces 429B Working out

dp1:(1,1)到(i,j) dp2:(n,m)到(i,j) dp3:(1,m)到(i,j) dp4:(n,1)到(i,j) 因为除边界点之外所有点都有可能是相遇点 而且要使相遇仅发生一次那么单体在相遇点前的方向和后的方向相同 各自不同 只有2种可能 #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #incl

基础简单DP

状态比较容易表示,转移方程比较好想,问题比较基本常见   递推.背包.LIS(最长递增序列),LCS(最长公共子序列) HDU 2048 数塔 由上往下推 状态数太多(100!) 可以由下往上推: dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+dp[i][j]) 储存的话就直接一个二维数组a[110][110] HDU2018 母牛 有一头母牛,它每年年初生一头小母牛.每头小母牛从第四个年头开始,每年年初也生一头小母牛.请编程实现在第n年的时候,共有多少头母牛? 斐