uva 10599 Robots(II) (DP)

这篇博客探讨了一种优化机器人清理垃圾的方法。在体育赛事或音乐会后的场地清洁中,公司提供能够拾取垃圾的机器人。机器人从西北角出发,沿着东或南方向移动,直到东南角结束。目标是使机器人清理最多含有垃圾的单元格。文章通过一个包含6行7列的示例地图,展示了如何使用动态规划找到清理最多垃圾单元格的不同路径,并给出了其中一个有效序列。输入数据包括地图的行数、列数和垃圾位置,输出是最大清理单元格数量、可能的清理方式数量以及一种清理顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

Figure 1: One 6x7 field map

Figure 2: Four sample solutions

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 N numbers 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

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

const int maxn = 110;
struct DP{
	int g_sum;
	int d_sum;
	vector<int> dir;
	vector<int> from;
}dp[maxn][maxn];
int mp[maxn][maxn] ,sum[maxn*maxn] , vis[maxn*maxn], N , C;

void initial(){
	for(int i = 0;i < maxn;i++){
		for(int j = 0;j < maxn;j++){
			dp[i][j].dir.clear();
			dp[i][j].d_sum = 0;
			dp[i][j].g_sum = 0;
			dp[i][j].from.clear();
			mp[i][j] = 0;
			sum[i*maxn+j] = 0;
			vis[maxn*i+j] = 0;
		}
	}
}

void readcase(){
	int r , c;
	while(scanf("%d%d" , &r , &c) && (r != 0||c != 0)){
		mp[r][c] = 1;
	}
}

void computing(){
	for(int r = 1;r <= N;r++){
		for(int c = 1;c <= C;c++){
			if(dp[r-1][c].g_sum < dp[r][c-1].g_sum){
				dp[r][c].dir = dp[r][c-1].dir;
				dp[r][c].from = dp[r][c-1].from;
				dp[r][c].d_sum = dp[r][c-1].d_sum;
				dp[r][c].g_sum = dp[r][c-1].g_sum;
			}else if(dp[r-1][c].g_sum > dp[r][c-1].g_sum){
				dp[r][c].dir = dp[r-1][c].dir;
				dp[r][c].from = dp[r-1][c].from;
				dp[r][c].d_sum = dp[r-1][c].d_sum;
				dp[r][c].g_sum = dp[r-1][c].g_sum;
			}else{
				dp[r][c].dir = dp[r-1][c].dir;
				dp[r][c].g_sum = dp[r-1][c].g_sum;
				for(int i = 0;i < dp[r-1][c].from.size();i++){
					vis[dp[r-1][c].from[i]] = 1;
					dp[r][c].d_sum += sum[dp[r-1][c].from[i]];
					dp[r][c].from.push_back(dp[r-1][c].from[i]);
				}
				for(int i = 0;i < dp[r][c-1].from.size();i++){
					if(vis[dp[r][c-1].from[i]] == 0){
						dp[r][c].from.push_back(dp[r][c-1].from[i]);
						dp[r][c].d_sum += sum[dp[r][c-1].from[i]];
					}
				}
				for(int i = 0;i < dp[r-1][c].from.size();i++){
					vis[dp[r-1][c].from[i]] = 0;
				}
			}
			if(mp[r][c]){
				dp[r][c].g_sum++;
				if(dp[r][c].d_sum == 0){
					dp[r][c].d_sum = 1;
				}
				dp[r][c].from.clear();
				dp[r][c].from.push_back(c+(r-1)*C);
				sum[c+(r-1)*C] = dp[r][c].d_sum;
				dp[r][c].dir.push_back(c+(r-1)*C);
			}
		}
	}
	cout << dp[N][C].g_sum << " " << dp[N][C].d_sum;
	for(int i = 0;i < dp[N][C].dir.size();i++){
		cout << " " << dp[N][C].dir[i];
	}
	cout << endl;
}

int main(){
	int t = 1;
	while(cin >> N >> C && (N != -1||C != -1)){
		initial();
		readcase();
		printf("CASE#%d: ",t++);
		computing();
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值