5294 挖地雷

5294 挖地雷

 

 时间限制: 1 s
 空间限制: 1000 KB
 题目等级 : 黄金 Gold
 
 
题目描述 Description

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

输入描述 Input Description

输入文件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表示有路径)。

 

输出描述 Output Description

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

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

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

 

样例输入 Sample Input

   

5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1

 

样例输出 Sample Output

   

1 3 4 5
27

 

数据范围及提示 Data Size & Hint

(N<=20)

 本题是一个经典的动态规划问题。很明显,题目规定所有路径都是单向的,所以满足无后效性原则和最优化原理。设W[i]为第i个地窖所藏有的地雷数,A[i][j]表示第i个地窖与第j个地窖之间是否有通路,F[i]为从第i个地窖开始最多可以挖出的地雷数,则有如下递归式:   F[i]=max{ W[i]+ F[j]} (i<j<=n , A[i][j]=true)   边界:F[n]=W[n]   于是就可以通过递推的方法,从后F(n)往前逐个找出所有的F[i],再从中找一个最大的即为问题2的解。对于具体所走的路径(问题1),可以通过一个向后的链接来实现。

最后一个点深坑

明明答案不唯一!!!!!!!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 const int MAXN=21;
 6 int a[MAXN];
 7 int map[MAXN][MAXN];
 8 int f[MAXN];
 9 int pre[MAXN+5];
10 int pd;
11 int out(int x)
12 {
13     if(pre[x]!=x)
14     out(pre[x]);
15     printf("%d ",x);
16 }
17 int main()
18 {
19     int n;
20     scanf("%d",&n);
21     for(int i=1;i<=n;i++)
22     scanf("%d",&a[i]);
23     for(int i=1;i<=n;i++)
24     f[i]=a[i];
25     pre[1]=1;
26     for(int i=1;i<=n-1;i++)
27     {
28         for(int j=i+1;j<=n;j++)
29         {
30             scanf("%d",&pd);
31             if(pd==1)map[i][j]=1;
32             else map[i][j]=0;
33         }
34     }
35     if(n==2&&map[1][2]==0)
36     {
37         printf("2\n%d",a[2]);
38         return 0;
39     }
40     for(int i=1;i<=n;i++)
41     {
42         for(int j=1;j<=n;j++)
43         {
44             if(map[i][j]==1)
45             {
46                 if(f[i]+a[j]>f[j])
47                 pre[j]=i;
48                 f[j]=max(f[i]+a[j],f[j]);
49                 
50             }
51         }
52     }
53     int ans=0;
54     int where;
55     for(int i=1;i<=n;i++)
56         if(f[i]>ans)ans=f[i],where=i;
57     out(where);
58     printf("\n");
59     printf("%d",ans);
60     return 0;
61 }

 

posted @ 2017-04-25 18:03  自为风月马前卒  阅读(258)  评论(0编辑  收藏  举报

Contact with me