zoukankan      html  css  js  c++  java
  • UVa 10599 Robots(II)(LIS变种)

    题意:

    给出一个矩阵的长和宽n,m,然后输入一些坐标,表示那个坐标上有垃圾(这道题里面每个坐标只有一个垃圾),然后机器人从(1,1)开始运动终点是(n,m)

    运动的方向只能是向下或者向右走,途中它要捡垃圾,目的是要令它捡的垃圾数最多,然后在能保证捡到的垃圾数最多的情况下,统计出有多少种方法,然后输出其中任意的一种方案。

    思路:

    可以把带垃圾的格子处理成一个sequence,然后求其LIS,只不过多了一层限制,就是机器人必须往斜下方向走罢了。

    中间涉及到到达终点的路径数以及打印路径。

    1. dp[i] == dp[j] + 1 : num[i] += num[j],

    2. dp[i] < dp[i] + 1 : num[i] = num[j].

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <climits>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 110;
    const int MAXD = 10010;
    bool g[MAXN][MAXN];
    int n, seq[MAXD], dp[MAXD], pre[MAXD], num[MAXD];
    int row, col;
    
    void solve()
    {
        n = 0;
        for (int i = 1; i <= row; ++i)
            for (int j = 1; j <= col; ++j)
                if (g[i][j])
                    seq[n++] = (i - 1) * col + j - 1;
    
        if (seq[n-1] != col * row - 1)
            seq[n++] = row * col - 1;
    
        memset(pre, -1, sizeof(pre));
        for (int i = 0; i < n; ++i)
        {
            dp[i] = 1, num[i] = 1;
    
            for (int j = 0; j < i; ++j)
                if ((seq[i]%col) >= (seq[j]%col))
                {
                    if (dp[i] < dp[j] + 1)
                        dp[i] = dp[j] + 1,
                        num[i] = num[j],
                        pre[i] = j;
                    else if (dp[i] == dp[j] + 1)
                        num[i] += num[j];
                }
        }        
        if (!g[row][col])
            --dp[n-1];
    }
    
    void outpath(int u)
    {
        if (pre[u] != -1)
            outpath(pre[u]);
        if (u != n - 1 || g[row][col])
            printf(" %d", seq[u] + 1);
    }
    
    int main()
    {
        int cases = 0;
        while (scanf("%d %d", &row, &col))
        {
            if (row == -1 && col == -1) 
                break;
    
            int x, y;
            memset(g, false, sizeof(g));
            while (scanf("%d %d", &x, &y) && x && y)
                g[x][y] = true;
    
            solve();
    
            printf("CASE#%d: %d %d", ++cases, dp[n-1], num[n-1]);
            outpath(n - 1);
            printf("\n");
        }
        return 0;
    }

     

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

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

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

  • 相关阅读:
    laravel、TP、YII框架的优缺点
    关于如何关闭Laravel中严格模式的两种方法
    Laravel扩展阿里云OSS对象存储
    Laravel权限管理的应用记录
    laravel原生MySQL之Group记录
    laravel导出Xlsx
    软件工程课的认识
    斗兽棋项目开发计划书
    斗兽棋测试计划说明书
    测试报告分析
  • 原文地址:https://www.cnblogs.com/kedebug/p/2789051.html
Copyright © 2011-2022 走看看