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>=1;i--)for(int j=i+1;j<=n;j++)if(mp[i][j])
if(dp[i]<dp[j]+a[i])
{
dp[i]=dp[j]+a[i];
nxt[i]=j;
}
int t=1;for(int i=2;i<=n;i++)if(dp[i]>dp[t]) t=i;
int ans=dp[t];
while(t!=0)
{
printf("%d ",t);
t=nxt[t];
}
printf("\n");
printf("%d\n",ans);
return 0;
}
</p>