UVA 10599 Robots (II)

Source: Internet
Author: User
Tags garbage collection valid

Original question:
Your Company provides robots, can be used to pick up litter from fields after sporting events and concerts. Before robots was assigned to a job, an aerial photograph of the field was marked with a grid. Each of the contains garbage is marked. All robots begin with the northwest corner and end their movement in the southeast corner. A robot can only move in and directions, either to
The East or south. Upon entering a cell that contains garbage, the robot can is programmed to pick it up before proceeding. Once a robot reaches its destination at the southeast corner it cannot be repositioned or reused. Since your expenses is directly proportional to the number of robots used for a particular job, you is interested in MAK ing the most out of them. Your task would is to use a robot
To clean the maximum number of cells containing garbage. Now there can is many ways to do the job, so your task would is to report that number of ways and show us one such sample . You see your robot can traverse many cells without picking up garbage, so for us a valid solution would is the sequence of Cell numbers that the robot cleans. The robots only clean cells, contain garbage; But the can program them to avoid picking up garbage from specific cells, if you would want to.



In the figure above we show a field map which has 6 rows and 7 columns. The cells in a field map is numbered in row major order starting from 1. For the example shown here, the following 7 cells contain garbage:2 (4 (1,4), 11 (2, 4), 13 (2, 6), 25 (4, 4), 28 ( 4, 7) and 41 (6, 7). Here cells is presented in cell number (row, column) format. Now the maximum number of cells, the can being cleaned is 5, and there am f different ways to does that:
< 2,4,11,13,28 >
< 2,4,11,13,41 >
< 2,4,11,25,28 >
< 2,4,11,25,41 >
Input
An input file consists of one or more field maps followed by a line containing ' -1-1 ' to signal the end of the input data . The description of a field map starts with the number of rows and the number of columns in the grid. Then in the subsequent lines, the garbage locations follows. The end of a field map is signaled by ' 0 0 '. Each garbage location consists of both integers, the row and column, separated by
A single space. The rows and columns is numbered as shown in Figure 1. The garbage locations is not being given in any specific order. and a location would not being reported twice for a field map. Please note this for all the test cases is required to solve, the field map would is of the at most rows and Colu Mns.
Output
The output for each test case is starts with the serial number (starting from 1) for the. Then the following integers is listed on a line:n the maximum number of cells that the robot can clean, C the number of ways that these n cells can is cleaned, and n numbers describing one possible sequence of cell numbers that the robot would Clean. As there can be C different such sequences and we is asking for only one sequence any valid sequence would do. Make sure this all these 2 + N integers for a test case is printed on a single line. There must be one space separating-consecutive integers and a space between the colon and the first integer on the Lin E. See the sample output format for a clear idea.
Sample Input
6 7
1 2
1 4
2 4
2 6
4 4
4 7
6 6
0 0
4 4
1 1
2 2
3 3
4 4
0 0
-1-1
Sample Output
Case#1:5 4 2 4 11 13 28
Case#2:4 1 1 6 11 16


English:
Give you the n*m grid, there are rubbish in the lattice, now let you send a robot, to pick up rubbish. The robot starts at (N,M) and only goes down or to the right. Ask you how many garbage you can pick up, and the number of paths to the most rubbish you have picked up, and the number of output paths. Note that the node of the path here is just a garbage lattice, see the example in the topic.



Code:



Brute-Force search Path Timeout code:



#include<bits/stdc++.h>
using namespace std;
const int maxn=101;
int dp[maxn][maxn];
int mat[maxn][maxn];
int n,m;
int cnt;
unordered_set<string> vis;

void dfs(int i,int j,string path)
{
    if(i==0||j==0)
        return;
    string tmp=path;
    if(mat[i][j])
    {
        tmp+=to_string((i-1)*m+j)+" ";
    }
    if(dp[i][j]==1&&mat[i][j])
    {
        if(vis.find(tmp)==vis.end())
        {
            vis.insert(tmp);
            cnt++;
            return;
        }
        else
        {
            return;
        }
    }
    else
    {
        if(dp[i-1][j]==dp[i][j-1])
        {
            dfs(i-1,j,tmp);
            dfs(i,j-1,tmp);
        }
        else
        {
            if(dp[i-1][j]>dp[i][j-1])
                dfs(i-1,j,tmp);
            else
                dfs(i,j-1,tmp);
        }
    }

}

int main()
{
    ios::sync_with_stdio(false);
    int t=1;
    while(cin>>n>>m)
    {
        vis.clear();
        if(n==-1)
            break;
        if(n==0||m==0)
            continue;
        int r,c;
        memset(mat,0,sizeof(mat));
        memset(dp,0,sizeof(dp));
        while(cin>>r>>c,r+c)
            mat[r][c]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(mat[i][j])
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1])+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        cout<<"CASE#"<<t++<<": "<<dp[n][m]<<" ";
        cnt=0;
        dfs(n,m,"");
        cout<<cnt<<" ";
        string tmp=*(vis.begin());
        stringstream ss;
        ss<<tmp;
        vector<int> v;
        int res;
        while(ss>>res)
        {
            v.push_back(res);
        }
        for(int i=v.size()-1;i>=0;i--)
        {
            if(i==0)
                cout<<v[i]<<endl;
            else
                cout<<v[i]<<" ";
        }
    }
    return 0;
}

The

Time-out code using the inverse adjacency table:


#include <bits / stdc ++. h>
using namespace std;
const int maxn = 101;
int dp [maxn] [maxn];
int mat [maxn] [maxn];
int n, m;
int cnt, flag;
set <int> G [10001];
vector <int> g [10001];
vector <int> path;
void dfs_path_num (int node)
{
    if (node == n * m)
    {
        cnt ++;
        return;
    }
    for (auto x: g [node])
    {
        dfs_path_num (x);
    }
}

void dfs_path (int node)
{
    if (flag)
        return;
    path.push_back (node);
    if (node == n * m)
    {
        flag = 1;
        return;
    }
    for (auto x: g [node])
    {
        dfs_path (x);
    }
}

int main ()
{
    ios :: sync_with_stdio (false);
    int t = 1;
    while (cin >> n >> m)
    {
        if (n ==-1)
            break;
        if (n == 0 || m == 0)
            continue;
        int r, c;
        cnt = 0;
        flag = 0;
        memset (mat, 0, sizeof (mat));
        memset (dp, 0, sizeof (dp));
        for (int i = 1; i <= n * m; i ++)
        {
            G [i] .clear ();
            g [i] .clear ();
        }
        path.clear ();
        int f = 0, e = 0;
        while (cin >> r >> c, r + c)
            mat [r] [c] = 1;
        if (mat [1] [1] == 1)
            f = 1;
        if (mat [n] [m] == 1)
            e = 1;
        for (int i = 1; i <= n; i ++)
        {
            for (int j = 1; j <= m; j ++)
            {
                if (mat [i] [j])
                    dp [i] [j] = max (dp [i-1] [j], dp [i] [j-1]) + 1;
                else
                    dp [i] [j] = max (dp [i-1] [j], dp [i] [j-1]);
            }
        }
        cout << "CASE #" << t ++ << ":" << dp [n] [m];
        mat [1] [1] = 1; // starting point
        mat [n] [m] = 1; // End point

        for (int j = 1; j <= m; j ++)
        {
            if (mat [1] [j-1])
                G [j] .insert (j-1);
            else
            {
                for (auto x: G [j-1])
                    G [j] .insert (x);
            }
        }
        if (mat [1] [1])
        {
            for (int i = 2; i <= n; i ++)
            {
                int tmp = (i-1) * m + 1;
                G [tmp] .insert (1);
            }
        }

        for (int i = 2; i <= n; i ++) // Build an inverse adjacency list
        {
            for (int j = 2; j <= m; j ++)
            {
                int tmp = (i-1) * m + j;
                int u = (i-1-1) * m + j;
                int l = (i-1) * m + j-1;
                if (dp [i-1] [j] == dp [i] [j-1])
                {
                    if (mat [i-1] [j] && mat [i] [j-1])
                    {
                        G [tmp] .insert (u);
                        G [tmp] .insert (l);
                    }
                    if (mat [i-1] [j] &&! mat [i] [j-1])
                    {
                        G [tmp] .insert (u);
                        for (auto x: G [l])
                            G [tmp] .insert (x);
                    }
                    if (! mat [i-1] [j] && mat [i] [j-1])
                    {
                        G [tmp] .insert (l);
                        for (auto x: G [u])
                            G [tmp] .insert (x);
                    }
                    if (! mat [i-1] [j] &&! mat [i] [j-1])
                    {
                        G [tmp] = G [u];
                        for (auto x: G [l])
                            G [tmp] .insert (x);
                    }
                }
                else
                {
                    if (dp [i-1] [j]> dp [i] [j-1])
                    {
                        if (mat [i-1] [j])
                            G [tmp] .insert (u);
                        else
                        {
                            for (auto x: G [u])
                                G [tmp] .insert (x);
                        }
                    }
                    else
                    {
                        if (mat [i] [j-1])
                            G [tmp] .insert (l);
                        else
                        {
                            for (auto x: G [l])
                                G [tmp] .insert (x);
                        }
                    }
                }
            }
        }
        for (int i = 1; i <= n; i ++)
        {
            for (int j = 1; j <= m; j ++)
            {
                if (mat [i] [j])
                {
                    int tmp = (i-1) * m + j;
                    for (auto x: G [tmp])
                        g [x] .push_back (tmp);
                }
            }
        }
        / *
        for (int i = 1; i <= n * m; i ++)
        {
            if (! g [i] .empty ())
            {
                cout << i << "->";
                for (auto x: g [i])
                    cout << x << "";
                cout << endl;
            }
        }
        * /
        dfs_path_num (1);
        cout << "" << cnt;
        dfs_path (1);

        if (f && e)
        {
            for (int i = 0; i <path.size (); i ++)
                cout << "" << path [i];
        }
        else
        {
            if (! f && e)
            {
                for (int i = 1; i <path.size (); i ++)
                    cout << "" << path [i];
            }
            else
            {
                if (f &&! e)
                {
                    for (int i = 0; i <path.size ()-1; i ++)
                        cout << "" << path [i];
                }
                else
                {
                    for (int i = 1; i <path.size ()-1; i ++)
                        cout << "" <<
path [i];
                 }
             }
         }
         cout << endl;
     }
     return 0;
}


Look at the code written by someone else's blog ~_~!!
Blog Link https://www.cnblogs.com/staginner/archive/2011/12/06/2278453.html


#include <bits / stdc ++. h>
using namespace std;
const int maxn = 101;
const int maxN = maxn * maxn;
int dp [maxN];
int mat [maxn] [maxn];
int seq [maxN], y [maxN], d [maxN], num [maxN], p [maxN];
int n, m;
int cnt, flag;

void dfs_path (int x)
{
    if (p [x]! =-1)
        dfs_path (p [x]);
    for (int i = 0; i <d [x]; i ++)
        cout << "" << seq [x];
}

int main ()
{
    ios :: sync_with_stdio (false);
    int t = 1;
    while (cin >> n >> m)
    {
        if (n ==-1)
            break;
        if (n == 0 || m == 0)
            continue;
        int r, c;
        memset (mat, 0, sizeof (mat));
        memset (dp, 0, sizeof (dp));
        memset (p, -1, sizeof (p));
        int f = 0, e = 0;
        int ind = 0;
        while (cin >> r >> c, r + c)
            mat [r] [c] = 1;

        for (int i = 1; i <= n; i ++)
        {
            for (int j = 1; j <= m; j ++)
            {
                if (mat [i] [j])
                {
                    seq [ind] = (i-1) * m + j;
                    y [ind] = j;
                    d [ind] = 1;
                    ind ++;
                }
            }
        }
        if (seq [ind-1]! = n * m)
        {
            seq [ind] = n * m;
            y [ind] = m;
            d [ind] = 0;
            ind ++;
        }
        fill (num, num + ind, 1);
        for (int i = 0; i <ind; i ++)
        {
            for (int j = 0; j <i; j ++)
            {
                if (y [j] <= y [i]) // The number of columns satisfies
                {
                    if (dp [j]> dp [i]) // f stores the most invasive incremental subsequence
                    {
                        dp [i] = dp [j];
                        num [i] = num [j]; // Number of storage paths
                        p [i] = j; // Store the previous node, used to output the path
                    }
                    else
                    {
                        if (dp [j] == dp [i]) // If the path lengths are equal, the cumulative path is
                            num [i] + = num [j];
                    }
                }
            }
            dp [i] + = d [i];
        }

        cout << "CASE #" << t ++ << ":" << dp [ind-1] << "" << num [ind-1];
        dfs_path (ind-1);
        cout << endl;
    }
    return 0;
}


Answer:



A total of 3 questions, the first question is quite simple, the use of two-dimensional dynamic programming directly solved.
The state transition equation is dp[i][j] records from the starting point to (I,J) the maximum number of garbage collection, Mat[i][j] Mark whether there is garbage



If MAT[I][J] has garbage
Dp[i][j]=max (dp[i-1][j],dp[i][j-1]) +1;
Otherwise
Dp[i][j]=max (Dp[i-1][j],dp[i][j-1]);



The second number of paths to solve the longest value is a little damndest.



Probably looked at the amount of data, the feeling will time out, decided to practice, the direct use of brute force search, use set record whether duplicate, the last set size is the number of paths.
Sure enough, timeout ~ ~-_-!



Next think of other ways, the most likely is to have a garbage lattice to create a diagram, the first to all (I,J) to establish a graph, in fact, a two-dimensional hash table, which contains a garbage lattice can reach (i,j) point number, the resulting is an inverse adjacency table. Remove only the garbage (I,J) nodes in the inverse adjacency table, build the diagram, and then look for the path number from the starting point. Consider the extreme situation, there are 100x100 lattice, each lattice has rubbish, then ..... The average number of numbers to keep in each lattice is 5,000, and if you have this data, the time complexity is definitely exploding.



I still hold a lucky mentality to try a try, sure enough time-out-_-~~



If the problem is so simple, there will not be more than 2000 people submitted, more than 400 people.



Looking at someone else's blog, almost all of the problems are converted to the longest increment subsequence problem. As a result, the robot can only go right and down. Therefore, the number of each garbage node is kept in a sequence seq, while the number of each node corresponding to the number of columns, in the use of the longest increment subsequence algorithm, limit the number of columns conditional requirements.



The longest increment sub-sequence problem is more convenient to find the path and the number of schemes ...


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.