zoukankan      html  css  js  c++  java
  • uva 10599




    本文出自   http://blog.csdn.net/shuangde800

    ---------------------------------------------------------------------------------


     

    题意

    给一个n*m大小的网格,有一些格子上面会有一个垃圾。机器人从左上角(1,1)出发,每次只能选择向右,或者向下走一步,
    终点是(n, m)。问最多可以捡多少个垃圾? 且捡最多垃圾有几种路径方案?注意路径方案指和有垃圾的格子有关。


    思路

    一开始没注意到方案只和有垃圾的格子有关,当作水题做,结果输出的方案数比样例大了非常多。然后又想了下。
    根据题意,路径只和有垃圾的格子有关,那么我们可以把这个网格抽象成一个图,图的节点就是有垃圾的格子,然后加上
    一些边把这些格子连起来。那么关键就是怎样加这些边?
    我们知道,对于点(i, j),只能选择走到(x, y) x>=i, y>=j,如果把所有有垃圾的点(x,y)都和(i,j)用边连起来,那么估计就要TLE了。

    对于点(i,j)首先,它可以直着往下走,那么往下碰到的第一个有垃圾的点,就可以和当前点连成一边,然后后面的忽略。
    然后还可以往右边走,和往右下角走,那么就从从当前行一直往下行枚举,对于每一行,从j+1列开始取第一个有垃圾的点,可以加一条边,然后这行后面的就忽略。

    注意,上面所谓的“加边”,只是一种思考方式,实际写代码时不需要真的去建图。

    f(i, j) 表示从点(i,j)出发最多可以捡到多少个垃圾。
    cnt(i, j) 表示从点(i, j)出发,捡最多垃圾有多少种方案。

    那么,
    f(i, j) = max{ f(x, y) + 1 | 点(x,y)是和(i,j)有边的相连的点} (“有边”的定义看上面分析)
    cnt(i, j) = sum( cnt(x, y) | 点(x, y)是和(i,j)相连的点 && f(x,y) = f(x,y)+1)

    输出路径很简单,记录一下转移过程即可。

    需要注意的是,点(1,1)和(n,m)可能会没有垃圾,这时我们就手动给他们增加一个垃圾,输出时不要输出这点就可以了



    代码

     
  • 相关阅读:
    ABAP中COLLECT的用法
    中文字符串提交乱码的解决方法
    我的Ubuntu系统
    SAP消息呈现
    ASP.NET博客站点全静态化的困扰
    JS利用函数修改全局变量
    让电脑速度增快几倍的法宝
    我的Ubuntu门派
    给老乡买本本的经历
    多事之秋
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3320321.html
Copyright © 2011-2022 走看看