Problem Statement
在一个地图上有 $N\ (N \le 20)$ 个地窖,每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
有若干行。
第 $1$ 行只有一个数字,表示地窖的个数 $N$。
第 $2$ 行有 $N$ 个数,分别表示每个地窖中的地雷个数。
第 $3$ 行至第 $N+1$ 行表示地窖之间的连接情况:
第 $3$ 行有 $n-1$ 个数($0$ 或 $1$),表示第一个地窖至第 $2$ 个、第 $3$ 个 $\dots$ 第 $n$ 个地窖有否路径连接。如第 $3$ 行为 $11000\cdots 0$,则表示第 $1$ 个地窖至第 $2$ 个地窖有路径,至第 $3$ 个地窖有路径,至第 $4$ 个地窖、第 $5$ 个 $\dots$ 第 $n$ 个地窖没有路径。
第 $4$ 行有 $n-2$ 个数,表示第二个地窖至第 $3$ 个、第 $4$ 个 $\dots$ 第 $n$ 个地窖有否路径连接。
……
第 $n+1$ 行有 $1$ 个数,表示第 $n-1$ 个地窖至第 $n$ 个地窖有否路径连接。(为 $0$ 表示没有路径,为 $1$ 表示有路径)。
Output
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
1
2
3
4
5
6
|
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
|
Sample Output
Solving
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
const int N = 22;
const int M = 0;
int val[N];
int pre[N];
int dp[N];//dp[i]表示以第i个地洞为终点时所能挖到的最大价值
int mp[N][N];
void print(int x)
{
if(pre[x]==0)
{
cout << x << ' ';
return;
}
print(pre[x]);
cout << x << ' ';
}
void solve()
{
int n;
cin >> n;
for(int i=1;i<=n;i++) cin >> val[i];
for(int i=1;i<=n-1;i++)
{
for(int j=i+1;j<=n;j++)
{
cin >> mp[i][j];
}
}
//初始化dp表每个洞为最终结束时所在洞的洞值
for(int i=1;i<=n;i++) dp[i] = val[i];
int ans = NINF;
int end = -1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
//如果j -> i为通路,且到达第j号洞的最大价值大于到达第i号洞的最大价值
if(mp[j][i]&&dp[j]+val[i]>dp[i])
{
dp[i] = dp[j] + val[i];
pre[i] = j;//记录前驱节点
}
}
}
for(int i=1;i<=n;i++)
{
if(dp[i]>ans)
{
ans = dp[i];
end = i;
}
}
print(end);
cout << endl;
cout << ans;
}
|