zoukankan      html  css  js  c++  java
  • POJ 2948 Martian Mining

    题意:如下图,有一种n*m的网格,每个格子里可能分别有两种矿物a[i][j]和b[i][j],在网格的上边和左边分别有这两种矿物的收集站。对每个网格,可以建立向上或者向左的传送带,将该格所有矿物传送。但是,传送带不能变方向,否则变方向之前的矿物会从传送带上掉落下来。比如,矿物如果从(i,j)传送到(i,j-1),再传送到(i-1,j-1),就会掉落。问最终能收集到的矿物最多为多少(两种矿物数量之和)。

    解法:首先,对于第(i,j)格,如果它向左传送,则应该让(i,0), (i,1)...(i,j-1)都向左传送。向上同理。

       设d[i][j][0]表示第(i,  j)格向左传送的情况下,矩形(0,0)-(i,j)所能收集到最多的矿石数,d[i][j][1]表示第(i,  j)格向上传送的情况下,矩形(0,0)-(i,j)所能收集到最多的矿石数。设wes[i][j]表示收集点在左边的矿石(i,0),(i,1)...(i,j)格共有多少,nor[i][j]表示收集点在上边的矿石(0,j),(1,j),(2,j)...(i,j)格共有多少。

       wes和nor数组递推易求,d数组的状态转移方程为:d[i][j][0] = wes[i][j] + max(d[i-1][j][0], d[i-1][j][1]),d[i][j][1] = nor[i][j] + max(d[i][j-1][0], d[i][j-1][1])。

    tag:网格类dp

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-11-18 17:03
     4  * File Name: DP-POJ-2948.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 
    10 using namespace std;
    11 
    12 #define CLR(x) memset(x, 0, sizeof(x))
    13 
    14 int n, m;
    15 int d[505][505][2];
    16 int x[505][505][2];
    17 int nor[505][505], wes[505][505];
    18 
    19 void init()
    20 {
    21     for (int t = 0; t < 2; ++ t)
    22         for (int i = 0; i < n; ++ i)
    23             for (int j = 0; j < m; ++ j)
    24                 scanf ("%d", &x[i][j][t]);
    25 
    26     CLR (nor); CLR (wes);
    27     for (int i = 0; i < n; ++ i)
    28         for (int j = 0; j < m; ++ j){
    29             wes[i][j] = (j ? x[i][j][0]+wes[i][j-1] : x[i][j][0]);
    30             nor[i][j] = (i ? x[i][j][1]+nor[i-1][j] : x[i][j][1]);
    31         }
    32 }
    33 
    34 int DP()
    35 {
    36     CLR (d);
    37     d[0][0][0] = x[0][0][0]; d[0][0][1] = x[0][0][1];
    38     for (int i = 0; i < n; ++ i)
    39         for (int j = 0; j < m; ++ j){
    40             if (!i && !j) continue;
    41             d[i][j][0] = wes[i][j];
    42             if (i)
    43                 d[i][j][0] += max(d[i-1][j][0], d[i-1][j][1]);
    44             d[i][j][1] = nor[i][j];
    45             if (j)
    46                 d[i][j][1] += max(d[i][j-1][0], d[i][j-1][1]);
    47         }
    48     return max(d[n-1][m-1][0], d[n-1][m-1][1]);
    49 }
    50 
    51 int main()
    52 {
    53     while (scanf ("%d%d", &n, &m) != EOF && n){    
    54         init();
    55         printf ("%d
    ", DP());        
    56     }
    57     return 0;
    58 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    程序员励志语录
    javaEE的十一种技术
    gui内函数调用顺序
    m文件中函数的执行顺序
    VC++与Matlab混合编程之引擎操作详解(6)数据类型mxArray的操作
    GUI(2)
    时间管理
    Matlab GUI界面
    matlab GUI(2)
    MATLAB GUI平台
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_2948.html
Copyright © 2011-2022 走看看