3-3 挖地雷 (20分) 动态规划

 

在一个地图上有n个地窖(n≤200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任意一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。

输入格式:

第一行:地窖的个数;

第二行:为依次每个地窖地雷的个数;

下面若干行:

xi yi //表示从xi可到yi,xi<yi。

最后一行为"0 0"表示结束。

输出格式:

k1-k2−…−kv //挖地雷的顺序 挖到最多的雷。

输入样例:

6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0

输出样例:

3-4-5-6
34

算法:

#include <iostream>
using namespace std;
int zuida_id=0;
int k=0;

int output(int i,int* c){  //递归寻找路径,把路径保存到数组c中
    if(c[i]==0) // 无前驱,为第一个地窖
    {
    c[++k]=i;
    return 0;
    }
    output(c[i],c);
    c[++k]=i;
    return 0;
    }


int main (){
    int n;
    cin>>n; 
    
    int num[n+1];  // 第i个地窖原有地雷数 
    int max[n+1];     // 记录若终点为i地窖,最多能挖的地雷数,初始化为第i个地窖原有地雷数 
    bool a[n+1][n+1]={0};     // 初始状态为 0, i到j有路则改为 1
    int c[n+1]={0};  // 先记录每个地窖最优前驱,后用来保存路径 
     
     
    // 输入每个地窖包含地雷 
    for(int i=1;i<=n;i++)
    {
        cin>>num[i];
    }
    //复制 
        for(int i=1;i<=n;i++)
    {
        max[i]=num[i];
    }
    //输入是否通路 
    while(1){
        int i,j;
        cin>>i>>j;
        if(i==0 && j==0) break; 
        a[i][j] = 1;
    }
    //寻找最优解 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][j]){  // i 到 j 有路 
                //max[j] = zhaodade(max[j],max[i]+num[j])
                if((max[i]+num[j])>max[j]){
                    max[j]=max[i]+num[j];
                    c[j] = i ;
                }
               
            }
        }
    }
     
    int zuida=max[1];
    for(int i=2;i<=n;i++){
        if(max[i]>zuida) {
            zuida=max[i];
            zuida_id=i;
        }
    }
    
    output(zuida_id,c);
    if(n==1) c[1]=1;   // 如果只有一个地窖,它没有前驱c[1]=0,可是输出路径时要输出1
    for(int i=1;i<=k;i++){
        cout<<c[i];
        if(i<k) cout<<"-";
    }
    cout<<endl;
    cout<<zuida<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/lvjingyuan/p/13908841.html