100 #P1415. *【动态规划练习】挖地雷[NOIP提高组1996]

*【动态规划练习】挖地雷[NOIP提高组1996]

Description

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

【输入格式】
有若干行。
第 $1$ 行只有一个数字,表示地窖的个数 $N$。
第 $2$ 行有 $N$ 个数,分别表示每个地窖中的地雷个数。
第 $3$ 行至第 $N+1$ 行表示地窖之间的连接情况:
第 $3$ 行有 $n-1$ 个数($0$ 或 $1$),表示第一个地窖至第 $2$ 个、第 $3$ 个、…、第 $n$ 个地窖有否路径连接。如第 $3$ 行为 $11000\cdots 0$,则表示第 $1$ 个地窖至第 $2$ 个地窖有路径,至第 $3$ 个地窖有路径,至第 $4$ 个地窖、第 $5$ 个、…、第 $n$ 个地窖没有路径。
第 $4$ 行有 $n-2$ 个数,表示第二个地窖至第 $3$ 个、第 $4$ 个、…、第 $n$ 个地窖有否路径连接。
……
第 $n+1$ 行有 $1$ 个数,表示第 $n-1$ 个地窖至第 $n$ 个地窖有否路径连接。(为 $0$ 表示没有路径,为 $1$ 表示有路径)。

【输出格式】
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。

【 样例输入】
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1

【样例输出】
1 3 4 5
27

Hint

#include<bits/stdc++.h>
using namespace std;
int a[21],dp[21],mp[21][21],nxt[21];
int main()
{
    int n;scanf("%d",&n);
	memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),dp[i]=a[i];
    for(int i=1;i<n;i++)for(int j=i+1;j<=n;j++) scanf("%d",&mp[i][j]);
for(int i=n-1;i&gt;=1;i--)for(int j=i+1;j&lt;=n;j++)if(mp[i][j])
    if(dp[i]&lt;dp[j]+a[i])
    {
        dp[i]=dp[j]+a[i];
        nxt[i]=j;
    }

int t=1;for(int i=2;i&lt;=n;i++)if(dp[i]&gt;dp[t]) t=i;
int ans=dp[t];
while(t!=0)
{
    printf("%d "&#44;t);
    t=nxt[t];
}
printf("\n");
printf("%d\n"&#44;ans);
return 0;

}

</p>