国王和金矿问题_动态规划

这是一个典型的0-1背包问题,工人总数可以看为背包的容量,金矿的个数可以看为物品的个数,金矿的含金量可以看作物品的价值,金矿的使用工人数可以看作物品所占空间数,这样一来就变成了0-1背包问题,关于0-1背包问题的解法可以看我这篇博客https://www.cnblogs.com/henuliulei/p/10041737.html代码只要把变量改改名字就完全可以适应这个问题了

代码如下,就不加详解了,注意金矿输入的顺序如下

 

代码如下

#include<bits/stdc++.h>
using namespace std;
int n;//金矿总个数
int array1[100];//金矿含金量
int array3[100];//金矿对应的工人数
int capacity;//矿工的总人数
int array2[100+1][100+1];//最大金矿收益
 int array4[100]={0};//记录采那些矿
int f(int n,int array1[],int array3[]){
 for(int i=0;i<=n;i++){
    array2[i][0]=0;
   }
   for(int j=0;j<=capacity;j++){
    array2[0][j]=0;
   }
   for(int i=1;i<=n;i++){
    for(int j=1;j<=capacity;j++){
        if(j<array3[i]){
            array2[i][j]=array2[i-1][j];
        }else{
           array2[i][j]=max(array2[i-1][j],array2[i-1][j-array3[i]]+array1[i]);
        }
    }
   }
   int s=capacity;
   for(int j=n;j>0;j--){
    if(array2[j][s]>array2[j-1][s]){
           array4[j]=1;
           s=s-array3[j];
    }
   }
   return array2[n][capacity];
}
int main()
{
    cout << "请输入金矿的总个数"<< endl;
    cin >> n;
    cout << "请依次输入每个的含金量" << endl;
    memset(array1,0,sizeof(array1));
    for(int i=1;i<=n;i++){
        cin >> array1[i] ;
    }
      cout << "请依次输入没个金矿的工人数" << endl;
      memset(array3,0,sizeof(array3));
    for(int i=1;i<=n;i++){
        cin >> array3[i] ;
    }
      cout << "请输入总共的工人数";
    cin >> capacity;
   memset(array2,0,sizeof(array2));
   memset(array4,0,sizeof(array4));
    cout << "可获的最大金矿" << f(n,array1,array3) << endl;
    cout << "需要采的矿是:";
    for(int i=1;i<=n;i++){
        if(array4[i]==1){
            cout <<""<< i << " ";
        }
    }

    return 0;
}

运行结果如下

猜你喜欢

转载自www.cnblogs.com/henuliulei/p/10041762.html