动规——挖地雷
挖地雷(神经病吧( ﹁ ﹁ ) ~→) DP
【问题描述】
在一个地图上有N个地窖(为啥地雷在地窖里。白菜表示不服( ﹁ ﹁ ) ~→)(N<=200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。
(结论:此为一位不被地雷炸会死被地雷炸也会死星人日常( ﹁ ﹁ ) ~→。)
【输入格式】
N //地窖的个数
W1,W2,……WN //每个地窖中的地雷数
X1,Y1 //表示从X1可到Y1
X2,Y2
……
0,0 //表示输入结束
【输出格式】
K1-K2-…-Kv //挖地雷的顺序
MAX //最多挖出的地雷数
【输入样例】
Mine.in
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
【输出样例】
Mine.out
3-4-5-6
34
【个人思路】
1.求出max[1](即w[1]);
2.求出max[2](即w[1]+w[2](有路)或w[2]);
......
最后求出所有之后比较一下,最大的那个就是最大值。
路径倒着输出。
【AC】(略长)
1 #include<iostream>
2
3 #include<cstdio>
4
5 using namespace std;
6
7 int main()
8
9 {
10
11 int l=1,n,k=0,x=1,y=1,p[205],up=1;
12
13 int w[205],max1[205],ma[205][2]={0},maxx=0;
14
15 bool wa[205][205]={0};
16
17 scanf("%d",&n);
18
19 for(int i=1;i<=n;i++)
20
21 {
22
23 scanf("%d",&w[i]);
24
25 }
26
27 while((x!=0)||(y!=0))
28
29 {
30
31 scanf("%d%d",&x,&y);
32
33 wa[x][y]=true;
34
35 }
36
37 wa[0][0]=false;
38
39 for(int i=1;i<=n;i++)
40
41 {
42
43 max1[i]=w[i];
44
45 ma[i][1]=w[i];
46
47 for(int q=i-1;q>=1;q--)
48
49 {
50
51 if(wa[q][i]==true&&ma[i][1]<max1[i]+ma[q][1])
52
53 {
54
55 ma[i][1]=max1[i]+ma[q][1];
56
57 ma[i][2]=q;
58
59 }
60
61 }
62
63 }
64
65 for(int i=1;i<=n;i++)
66
67 {
68
69 if(ma[i][1]>maxx)
70
71 {
72
73 maxx=ma[i][1];
74
75 p[0]=i;
76
77 l=i;
78
79 }
80
81
82
83 }
84
85 while(ma[l][2]!=0)
86
87 {
88
89 p[up]=ma[l][2];
90
91 up++;
92
93 l=ma[l][2];
94
95 }
96
97 for(int i=up-1;p[i-1]!=0;i--)
98
99 cout<<p[i]<<"-";
100
101 cout<<p[0]<<endl;
102
103 printf("%d",maxx);
104
105 return 0;
106
107 }