洛谷P2196 挖地雷 [2017年4月计划 动态规划13]

P2196 挖地雷

题目背景

NOIp1996提高组第三题

题目描述

在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。

输入输出格式

输入格式:

输入文件mine.in有若干行。

第1行只有一个数字,表示地窖的个数N。

第2行有N个数,分别表示每个地窖中的地雷个数。

第3行至第N+1行表示地窖之间的连接情况:

第3行有n-1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为1 1 0 0 0 … 0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。

第4行有n-2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。

… …

第n+1行有1个数,表示第n-1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。

输出格式:

输出文件wdl.out有两行数据。

第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。

第二行只有一个数,表示能挖到的最多地雷数。

输入输出样例

输入样例#1:
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
输出样例#1:
1 3 4 5
27

先挂上代码,有几个地方细思极恐,需要仔细想想
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#define max(a, b) ((a) > (b)) ? (a) : (b);
#define min(a, b) ((a) < (b)) ? (b) : (a);
inline int read()
{
	int x = 0;char ch = getchar();char c = ch;
	while(ch > '9' || ch < '0')c = ch,ch = getchar();
	while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
	if(c == '-')return -1 * x;
	return x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = 20 + 10;
int n;
int b[MAXN][MAXN],num[MAXN],f[MAXN],path[MAXN];
int a[MAXN];
int cnt;

int main()
{
	n = read();
	for(int i = 1;i <= n;i ++)
	{
		num[i] = read();
	}
	for(int i = 1;i <= n - 1;i ++)
	{
		int temp = n - i;
		for(int j = 1;j <= temp;j ++)
		{
			b[i][j + i] = read();
		}
	}
	f[n] = num[n];
	for(int i = n - 1;i >= 1;i --)
	{
		f[i] = num[i];
		for(int j = n;j >= i ;j --)
		{
			if(b[i][j] && f[i] < f[j] + num[i])
			{
				f[i] = f[j] + num[i];
				path[i] = j;
			}
		}
	}
	int ans,max = -1;
	for(int i = 1;i <= n;i ++)
	{
		if(max < f[i])
		{
			ans = i;
			max = f[i];
		}
	}
	while(ans)
	{
		printf("%d ", ans);
		ans = path[ans];
	}
	printf("
%d", max);
	return 0;
}





原文地址:https://www.cnblogs.com/huibixiaoxing/p/6744538.html