您的位置:首页 > 其它

Robots(II) - UVa 10599 dp

2014-08-06 00:01 323 查看
Problem K

Robots(II)
Time Limit

1 Second
Your company provides robots that can be used to pick up litter from fields after sporting events and concerts. Before robots are assigned to a job, an aerial photograph of the field is marked with a grid. Each location in the grid that contains garbage
is marked. All robots begin in the Northwest corner and end their movement in the Southeast corner. A robot can only move in two directions, either to the East or South. Upon entering a cell that contains garbage, the robot can be 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 are directly proportional to the number of robots used for a particular job, you are interested in making the most out
of them. Your task would be to use a robot to clean the maximum number of cells containing garbage. Now there can be many ways to do this job, so your task would be 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 be the sequence of cell numbers that the robot cleans. The robots only clean cells that contain garbage; but you 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 that has 6 rows and 7 columns. The cells in a field map are numbered in row major order starting from 1. For the example shown here, the following 7 cells contain garbage: 2 (1,2), 4 (1,4), 11 (2, 4), 13 (2,
6), 25 (4, 4), 28 (4, 7) and 41 (6, 7)
. Here cells are presented in cell_number (row, column) format. Now the maximum number of cells that can be cleaned is 5, and there are 4 different ways to do
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 two integers, the row and column, separated by a single space. The rows and columns are numbered as shown in Figure 1.
The garbage locations will not be given in any specific order. And a location would not be reported twice for a field map. Please note that for all the test cases you are required to solve, the field map would be of at most 100 rows and 100 columns.



Output

The output for each test case starts with the serial number (starting from 1) for that test case. Then the following integers are 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 be cleaned, and Nnumbers describing one possible sequence of cell numbers that the robot will clean. As there can be C different such sequences and we are asking for only one
sequence any valid sequence would do. Make sure that all these 2+N integers for a test case are printed on a single line. There must be one space separating two consecutive integers and a space between the colon and the first integer on the
line. See the sample output format for a clear idea.





Sample Input

Output for 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

CASE#1: 5 4 2 4 11 13 28

CASE#2: 4 1 1 6 11 16

题意:每次只能往右或往下走,输出最多捡多少垃圾,情况数目,和字典序最小的路径。

思路:dp[i][j][0]表示i行j列后最多捡多少垃圾,dp[i][j][2]表示上一个垃圾是哪个点的,如果当前的点有垃圾,那么dp[i][j][2]为这个点dp[i][j][3]表示上一个垃圾是哪个点的。情况数目让所有有垃圾的点按之后最多捡到的垃圾数目排序,递推得到结果。这个题我写得比较乱,但是竟然1A了,看来最近练习dp还是有些作用的。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{ int x,y,m,p;
}dian[10010];
bool cmp(node a,node b)
{ return a.m<b.m;}
int dp[110][110][4],num[110][110],x,y,n,m,len;
long long ans;
void right(int i,int j)
{ dp[i][j][0]=dp[i][j+1][0];
  dp[i][j][2]=dp[i][j+1][2];
}
void down(int i,int j)
{ dp[i][j][0]=dp[i+1][j][0];
  dp[i][j][2]=dp[i+1][j][2];
}
void add(int i,int j)
{ if(num[i][j]==1)
  { dp[i][j][0]++;
    dp[i][j][3]=dp[i][j][2];
    dp[i][j][2]=(i-1)*m+j;
  }
}
void solve(int S)
{ y=S%m;
  if(y==0)
   y=m;
  x=(S-y)/m+1;
}
int main()
{ int t=0,i,j,k;
  while(~scanf("%d%d",&n,&m) && n!=-1)
  { memset(dp,0,sizeof(dp));
    memset(num,0,sizeof(num));
    len=0;
    while(~scanf("%d%d",&x,&y) && x+y)
    { len++;
      dian[len].x=x;
      dian[len].y=y;
      num[x][y]=1;
    }
    dp
[m+1][1]=1;
    for(i=m;i>=1;i--)
    { right(n,i);
      add(n,i);
    }
    for(i=n-1;i>=1;i--)
    { down(i,m);
      add(i,m);
      for(j=m-1;j>=1;j--)
      { if(dp[i][j+1][0]>dp[i+1][j][0])
         right(i,j);
        else if(dp[i][j+1][0]<dp[i+1][j][0])
         down(i,j);
        else if(dp[i][j+1][0]==dp[i+1][j][0])
        { if(dp[i][j+1][2]==dp[i+1][j][2])
           down(i,j);
          else
          { if(dp[i][j+1][2]<dp[i+1][j][2])
             right(i,j);
            else if(dp[i][j+1][2]>dp[i+1][j][2])
             down(i,j);
          }
        }
        add(i,j);
      }
    }
    for(i=1;i<=len;i++)
     dian[i].m=dp[dian[i].x][dian[i].y][0];
    sort(dian+1,dian+1+len,cmp);
    for(i=1;i<=len;i++)
    { if(dian[i].m==1)
      { dian[i].p=1;
        continue;
      }
      else
      { dian[i].p=0;
        k=dian[i].m;
        for(j=i-1;j>=1;j--)
        { if(dian[j].m==k)
           continue;
          if(k-dian[j].m>=2)
           break;
          if(dian[j].x>=dian[i].x && dian[j].y>=dian[i].y)
           dian[i].p+=dian[j].p;
        }
      }
    }
    ans=0;
    for(i=len;i>=1;i--)
    { if(dian[i].m!=dp[1][1][0])
       break;
      ans+=dian[i].p;
    }
    printf("CASE#%d: %d %lld",++t,dp[1][1][0],ans);
    k=dp[1][1][0];
    solve(dp[1][1][2]);
    for(i=1;i<=k;i++)
    { printf(" %d",(x-1)*m+y);
      solve(dp[x][y][3]);
    }
    printf("\n");
  }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: