挖地雷——动态规划

在一个地图上有n个地窖(n≤200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任意一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。

输入格式:

第一行:地窖的个数;

第二行:为依次每个地窖地雷的个数;

下面若干行:

xi yi //表示从xi可到yi,xi<yi。

最后一行为"0 0"表示结束。

输出格式:

k1-k2−…−kv //挖地雷的顺序 挖到最多的雷。

输入样例:

6

5 10 20 5 4 5

1 2

1 4

2 4

3 4

4 5

4 6

5 6

0 0

输出样例:

3-4-5-6

34

程序答案:

注:

nums[i]为第i个地窖埋的地雷数;
count[i]为选择第i个地窖挖时的最大地雷数,则
count[i] = max{nums[i] + count[j] | 地窖i、j相连} i<j<=n;
path[i]记录挖完第i个地窖后,下一个菜窖选择哪一个挖的地雷数最多。 

#include <iostream>
using namespace std;

const int MAX = 210; 
int conn[MAX][MAX] = {0}; //记录两个菜窖是否联通 
int count[MAX] = {0}; //挖到第i个地窖时的最大地雷数 
int path[MAX] = {0}; //记录挖地雷的最优路径 
int main() {
	int n;
	cin >> n;
	int nums[n];
	for (int i = 1; i <= n; i++)  cin >> nums[i];
	while (true) {
		int a, b;
		cin >> a >> b;
		if (a == 0 && b == 0) break;
		conn[a][b] = 1;
	}

	//从右至左依次填表 
	for (int i = n; i >= 1; i--) {
		count[i] = nums[i];
		for (int j = i + 1; j <= n; j++) {
			if (conn[i][j] == 1) {
				int tmp = nums[i] + count[j];
				if (tmp > count[i]) {
					count[i] = tmp;
					path[i] = j;
				}
			}
		}
	
	}
	//比较从哪个菜窖开始挖地雷数最多 
	int max = 0; //挖到最多的地雷数 
	int id = 1; //从哪个菜窖开始挖 
	for (int i = 1; i <= n; i++) {
		if (count[i] > max) {
			max = count[i];
			id = i;
		}		
	}
	//输出挖地雷路径 
	cout << id;
	while (path[id] > 0) { //path[i]为0时,表示无连接,路径结束 
		cout << "-" << path[id];
		id = path[id];
	}
	cout << endl << max << endl;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值