挖地雷
题目
在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。例如:
Input
Output
K1 K2,……,KV (挖地雷的顺序)
MAX (挖地雷的数量)
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
解题思路
枚举n个地窖i,{阶段}
里面再枚举i前面的地窖j,{状态}
再判断是地窖j是否能通向地窖i,能的话记下来,
地窖i的状态等于能通过来的地窖中能挖的最多的那个加地窖i本身的地雷。{决策}
f[i]表示到达第i个地窖能挖到的最大地雷,
g表示1~i个地窖中能到达地窖i的地窖中能挖到的最大地雷。
g=0,g=max(g,f [ j ]) , f[i]=g+a[i] , 1<=i<=n,1<=j<i
代码
#include<iostream>
using namespace std;
long long n,m,a[101],b[101][101],f[101],c[101],ans,d,e[101],h;
void in(){
cin>>n;for(int i=1;i<=n;i++){
cin>>a[i];
}for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
cin>>b[i][j];
}
}f[n]=a[n];c[n]=1000;
}void DP(){
for(int i=1;i<=n;i++){
int g=0;
for(int j=1;j<i;j++){
if(b[j][i]==0){
continue;
}if(f[j]>=g){
g=f[j];
c[i]=j;//记录地窖i从哪个地窖来
}
}f[i]=a[i]+g;
}
}void out(){
for(int i=1;i<=n;i++){
if(ans<=f[i]){//找出能挖到的最多地雷
ans=f[i];
d=i;//最多地雷的编号
}
}
while(c[d]!=0){//这个地窖经过就继续记录
e[h]=d;//记录经过地窖
d=c[d];
h++;
}cout<<d<<" ";
for(int i=h-1;i>=0;i--){
cout<<e[i]<<" ";
} cout<<endl;
cout<<ans;
}
int main(){
in();
DP();
out();
}