题目描述
在一个地图上有 N N N个地窖 ( N ≤ 20 ) (N \le 20) (N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
有若干行。
第 1 1 1行只有一个数字,表示地窖的个数 N N N。
第 2 2 2行有 N N N个数,分别表示每个地窖中的地雷个数。
第 3 3 3行至第 N + 1 N+1 N+1行表示地窖之间的连接情况:
第 3 3 3行有 n − 1 n-1 n−1个数( 0 0 0或 1 1 1),表示第一个地窖至第 2 2 2个、第 3 3 3个、…、第 n n n个地窖有否路径连接。如第 3 3 3行为 11000 … 0 1 1 0 0 0 … 0 11000…0,则表示第 1 1 1个地窖至第 2 2 2个地窖有路径,至第 3 3 3个地窖有路径,至第 4 4 4个地窖、第 5 5 5个、…、第 n n n个地窖没有路径。
第 4 4 4行有 n − 2 n-2 n−2个数,表示第二个地窖至第 3 3 3个、第 4 4 4个、…、第 n n n个地窖有否路径连接。
… …
第 n + 1 n+1 n+1行有 1 1 1个数,表示第 n − 1 n-1 n−1个地窖至第 n n n个地窖有否路径连接。(为 0 0 0表示没有路径,为 1 1 1表示有路径)。
输出格式
有两行
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
样例 #1
样例输入 #1
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
样例输出 #1
1 3 4 5
27
提示
【题目来源】
NOIP 1996 提高组第三题
这题有个坑点没说清楚, 就是只能从前往后挖,序号是递增的
#include <bits/stdc++.h>
using namespace std;
stack<int> stk;
int N,ans;
bool judge[25][25];
int n[25];
int f[25]; // f[i] 表示 "以 i 号点为结尾的路径" 的最大地雷数
int q[25];
//状态转移方程:f[i] = max(f[i],f[j] + n[i]); (judge[i][j] = true)
int main()
{
cin >> N;
for(int i =1; i <= N; i ++) {
cin >> n[i];
f[i] = n[i]; //以i结尾的最大地雷初始化为自己
}
for(int i = 1; i < N; i ++) {
for(int j = i + 1; j <= N; j ++) {
cin >> judge[i][j];
}
}
for(int i = 1; i <= N; i ++) {
for(int j = 1; j < i; j ++) {
if(judge[j][i])
{
if(f[i] < f[j] + n[i])
{
f[i] = f[j] + n[i];
q[i] = j; //表示i的最大状态是从j转移来的
}
}
}
}
int index = 0; //用来索引整条路径
for(int i = 1; i <= N; i ++) {
if(ans < f[i])
{
ans = f[i];
index = i;
}
}
while(index) {
stk.push(index);
index = q[index];
}
while(!stk.empty()) {
cout << stk.top() << ' ';
stk.pop();
}
cout << endl << ans;
return 0;
}