zoukankan      html  css  js  c++  java
  • cf 429B Working out(简单dp)

    B. Working out
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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 the i-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 workout a[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.

    Examples
    input
    3 3
    100 100 100
    100 1 100
    100 100 100
    output
    800
    Note

    Iahub will choose exercises a[1][1] → a[1][2] → a[2][2] → a[3][2] → a[3][3]. Iahubina will choose exercises a[3][1] → a[2][1] → a[2][2] → a[2][3] → a[1][3].

    给一个n*m的方格,A从左上角走到右下角,B从左下角走到右上角,路线交叉处的权值不算,问两条路线权值之和最大值。要求:两条路线只在一点交叉。

    可以枚举交叉点,求该点到四个角落的权值之和。到每个角的权值都可以dp得到最大值。从左上角顺时针得到0,1,2,3四个方向。


     
    两幅图的权值之和分别是: 
    dp[i][j-1][0] + dp[i-1][j][1] + dp[i][j+1][2] + dp[i+1][j][3] 
    dp[i][j-1][3] + dp[i-1][j][0] + dp[i][j+1][1] + dp[i+1][j][2]

    还有需注意的是,交叉点只在(n-2)*(m-2)里面这个矩形里变化(否则一个角上的矩形会不存在)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAXN = 1010;
     5 __int64 a[MAXN][MAXN];
     6 __int64 dp[MAXN][MAXN][4];//0, 1, 2, 3分别代表左上,右上,右下,左下
     7 
     8 int main()
     9 {
    10 
    11     int n, m;
    12     int i, j;
    13 
    14     while (~scanf("%d%d", &n, &m)) {
    15         for (i = 1; i <= n; ++i) {
    16             for (j = 1; j <= m; ++j) {
    17                 scanf("%I64d", &a[i][j]);
    18             }
    19         }
    20         memset(dp, 0, sizeof(dp));
    21 
    22         for (i = 1; i <= n; ++i) {
    23             for (j = 1; j <= m; ++j) {
    24                 dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j - 1][0]) + a[i][j];
    25             }
    26         }
    27         for (i = 1; i <= n; ++i) {
    28             for (j = m; j >= 1; --j) {
    29                 dp[i][j][1] = max(dp[i - 1][j][1], dp[i][j + 1][1]) + a[i][j];
    30             }
    31         }
    32         for (i = n; i >= 1; --i) {
    33             for (j = m; j >= 1; --j) {
    34                 dp[i][j][2] = max(dp[i + 1][j][2], dp[i][j + 1][2]) + a[i][j];
    35             }
    36         }
    37         for (i = n; i >= 1; --i) {
    38             for (j = 1; j <= m; ++j) {
    39                 dp[i][j][3] = max(dp[i + 1][j][3], dp[i][j - 1][3]) + a[i][j];
    40             }
    41         }
    42 
    43         __int64 ans = 0;
    44         for (i = 2; i < n; ++i) {
    45             for (j = 2; j < m; ++j) {
    46                 ans = max(ans, dp[i][j - 1][0] + dp[i - 1][j][1] + dp[i][j + 1][2] + dp[i + 1][j][3]);
    47                 ans = max(ans, dp[i][j - 1][3] + dp[i - 1][j][0] + dp[i][j + 1][1] + dp[i + 1][j][2]);
    48             }
    49         }
    50         printf("%I64d
    ", ans);
    51     }
    52 
    53     return 0;
    54 }
  • 相关阅读:
    BZOJ2563 阿狸和桃子的游戏
    BZOJ2460 Beijing2011元素(线性基+贪心)
    BZOJ2458 Beijing2011最小三角形(分治)
    BZOJ2442 Usaco2011 Open修剪草坪(动态规划+单调队列)
    Luogu2257 YY的GCD/BZOJ2818 Gcd加强版(莫比乌斯反演+线性筛)
    BZOJ2428 HAOI2006均分数据(模拟退火)
    BZOJ2440 中山市选2011完全平方数(容斥原理+莫比乌斯函数)
    洛谷 P1783 海滩防御 解题报告
    洛谷 P2431 正妹吃月饼 解题报告
    洛谷 P2751 [USACO4.2]工序安排Job Processing 解题报告
  • 原文地址:https://www.cnblogs.com/gongpixin/p/6731844.html
Copyright © 2011-2022 走看看