参考:http://www.cnblogs.com/sdjl/articles/1274312.html 感谢 作者 SDJL
问题: 金矿问题
例如:
总共100个人, 5座金矿
每一个金矿需要x人, 能产出y金. 如果不能满足x人将产出为0,挖过的人将不再挖.如何利用100人使得挖出的金矿最多
100 5
77 92
22 22
29 87
50 46
99 90
简单分析:
1.对于每个金矿只有2种情况,挖或者不挖. 所以可以对每个金矿分2种情况讨论.将其余的金矿看成一个整体.
2.如果挖该金矿(假设此时人数足够,不够的话直接跳过这个金矿),将产出y, 人数减少x. 对剩下的人数和剩下金矿, 选中某个金矿继续分2种情况讨论
3.如果不玩我该金矿.将产出0,人数不减. 对剩下的人数和剩下金矿, 选中某个金矿继续分2种情况讨论
4.比较以上2种情况哪个更大则返回哪个
5.依次递归到最后一个金矿.判断此时人数还够不够. 就能递归回去
测试代码:
#include<iostream>
#include <fstream>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int allp;//总人数
int allm;//总金矿数
int goals[100];//每个金矿产金量,最多100个金矿
int nump[100];//每个金矿需要的人数
int maxgoals[1000][100];//在剩下的人数基础上,剩下几个金矿最多产量.设最多1000人
void init()
{
ifstream in("beibao0.in");
in>>allp>>allm;
for (int i=0;i<allm;i++)
{
in>>nump[i]>>goals[i];
}
in.close();
for(int i=0;i<1000;i++)
{
for (int j=0;j<100;j++)
{
maxgoals[i][j]=-1;
}
}
}
int calcMaxGoals(int p,int m)//参数:剩下的人数和第几个金矿
{
if (maxgoals[p][m]!=-1)
{
return maxgoals[p][m];
}
if (p<nump[m])
{
if(m==0)
{
return 0;
}
else
{
maxgoals[p][m]=calcMaxGoals(p,m-1);
return maxgoals[p][m];
}
}
else
{
if(m==0)
{
maxgoals[p][m]= goals[m];
return maxgoals[p][m];
}
maxgoals[p][m]=max(calcMaxGoals(p,m-1),calcMaxGoals(p-nump[m],m-1)+goals[m]);
return maxgoals[p][m];
}
}
void main()
{
init();
cout<<calcMaxGoals(allp,allm-1);
cin.get();
}
浙公网安备 33010602011771号