算法-贪心法-背包问题

 对于背包问题(这个是背包问题,不是0/1背包问题),贪心有三种策略:

1、从物品中选取价值最大的放入。

2、从物品中选区重量最小的放入。

3、选取物品的价值与重量的比值大的放入。

第一第二种不能保证得到最优解,第三种有的资料说也不能保证得到最优解,但是能得到最优的近似解。这里选取第三种方法:

1、先选取比值最大的物品。

2、比较其重量是否小于背包容量,如果小,就放入,如果大于背包容量,就对其进行切割。

3、循环第一步,直到背包容量等于0。

#include<iostream>
#include<iomanip>
using namespace std;

//找到比值最大的值以及坐标返回坐标,更新最大值
int maxIndex(int n,float max,float a[5])
{
	int index=0;
	for(int i = 1; i < n; i++)
	{
        if(a[i] > max)
		{
            max = a[i];
            index = i;
        }
    }
	return index;
}

int main()
{
    int n=5;   //物品数
    float c=10; //背包容量
    float res = 0;  //最大价值
    
    
	float v[5]={6,3,5,4,6};   //物品价值
	float w[5]={2,2,6,5,4};   //物品重量
    float a[5];   //物品价值比值
	float &max = a[0];  //比值最大
    int index = 0;  //比值最大值的下标
	float visit[5]={0}; //该物品取多少

	//求出物品价值的比值
	for(int i=0;i<5;i++)
		a[i]=v[i]/w[i];
    index =maxIndex(n,max,a);
    //c = 0
    while(c > 0)
	{
        if(w[index] <= c)
		{	//如果单价最高者放得下,全放进去
			visit[index]=1;
            res += v[index];
			c -= w[index];  
            a[index] = 0;   //删除该物品
			index =maxIndex(n,max,a);//继续找比值最大
        }
		else
		{   //如果放不下,则将物品进行切分
            res += c * a[index];  //剩余的装满
			visit[index]=c/w[index];
            c = 0;
        }
    }
	cout<<setiosflags(ios::fixed)<<setprecision(2);
	cout<<"物品取得量:"<<endl;
	for(int i=0;i<n;i++)
	{
		cout<<"第"<<i+1<<"个物品:";
		cout<<visit[i]<<"   "<<visit[i]*v[i]<<endl;
	}
    cout<<endl<<"最大价值是:"<<res<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40452317/article/details/90145533