算法:动态规划之金矿问题(时间复杂度O(n*w))

来源:互联网 发布:mac怎么下载lol美服 编辑:程序博客网 时间:2024/06/05 20:55

问题描述:

有一个国家发现了5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。参与挖矿工人的总数是10人。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿。要求用程序求解出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?

//int g[]表示金矿金子数;int p[]表示需要矿工数;n金矿数;w矿工数/**********************************************************************///解法一:只记录上一层数据,优化空间结构;int GettheMostGold(int n, int w, int g[], int p[]){      if(n<1 || w<1)return 0;vector<int> vecpre(w+1,0);//保存上一行的值vector<int> vec(w+1,0);int i,j;for(i=0;i<=w;i++)//为第一行赋值{if(i<p[0])vecpre[i]=0;elsevecpre[i]=g[0];   }for(i=1;i<n;i++)//更新数据{for(j=1;j<=w;j++){if(j<p[i])//人不够,没采vec[j]=vecpre[j];else//人够,可采可不采,选择效益最好的vec[j]=max(vecpre[j], vecpre[j-p[i]]+g[i]);}vecpre=vec;}int nret = vec[w];//最右边值即为所求return nret;}//解法二:记录所有的数据,可以确定选了哪几个对象//vecchoose 用来保存选择的对象int GettheMostGold(int n, int w, int g[], int p[], vector<int> &vecchoose){  if (n<1 || w<1)          return 0;vector<vector<int>> vecall;for (int i=0;i<n;i++)//初始化列表{vector<int> vec(w+1,0);vecall.push_back(vec);}for (int i=0;i<=w;i++)//初始化第一行数据{if (i>=p[0])   vecall[0][i]=g[0];else   vecall[0][i]=0;}for (int i=1;i<n;i++)//填表{for (int j=1;j<=w;j++){if (j<p[i])//人数不够,采不了    vecall[i][j]=vecall[i-1][j];else//人数充足,可采可不采,选择效益最好的vecall[i][j]=max(vecall[i-1][j-p[i]]+g[i], vecall[i-1][j]);}}Findwhat(vecchoose,vecall,n-1,w,g,p);//返回选中的return vecall[n-1][w];}void Findwhat(vector<int> &vecchoose, vector<vector<int>> &vec, int i, int j, int g[], int p[]){//回溯法if (i>0){if (vec[i][j]==vec[i-1][j])//说明没有选择第i项{Findwhat(vecchoose,vec,i-1,j,g,p);}else if(j>=p[i] && vec[i][j]==vec[i-1][j-p[i]]+g[i])//说明选择了第i项{vecchoose.push_back(i);Findwhat(vecchoose,vec,i-1,j-p[i],g,p);}}else{//第一行,如果不够那么说明选了第一行int nvalue=0;for (int i=0;i<vecchoose.size();i++){nvalue+=g[vecchoose[i]];}if(nvalue<vec[vec.size()-1][vec[0].size()-1])vecchoose.push_back(0);}return;}


阅读全文
0 0
原创粉丝点击