蓝桥杯之Remember the A La Mode-需要谨慎处理逻辑关系(c++实现)

上文链接:蓝桥杯之能量项链-类比哈夫曼树(c++实现)


资源限制

时间限制:1.0s 内存限制:256.0MB

问题描述

Hugh Samston经营着一个为今年的ICPC世界总决赛的参与者提供甜点的餐饮服务。他将会提供上面有冰激凌的饼片。为了满足不同的需求,他准备了许多不同的饼片和冰激凌。
  Hugh希望以一份饼片上一份冰激凌的方式来提供甜点。然而,作为一个商人,他希望能赚到尽可能多的钱。他知道不同种类的饼片和冰激凌组合的价格,也知道那些冰激凌和那些饼片不能组合在一起。
  Hugh想根据每种饼片和冰激凌的数量,以及之前提到的不同组合的情况,确定他能获得的利润的范围。

输入格式

测试数据的输入一定会满足的格式。
  输入的第一行包含两个整数P, I,分别表示饼片和冰激凌的种类数。
  接下来一行包含P个整数,表示每种类型饼片的数量。
  接下来一行包含I个整数,表示每种类型冰激凌的数量。
  接下来P行,每行包含I个实数,表示每种类型饼片和冰激凌组合的结果。
  如果这种饼片和这种冰激凌可以组合,则为一个(0,10)的实数,表示这种组合的收益。
  否则,则为-1,表示这两种之间不能组合。

输出格式

输出一行,以"(最小收益) to (最大收益)"的方式输出利润的范围。

请注意:所有的饼片和冰激凌都必须用完。

样例输入

2 3
40 50
27 30 33
1.11 1.27 0.70
-1 2 0.34

样例输出

91.70 to 105.87

数据规模和约定

0 < P,I <= 50,每种类型饼片或冰激凌数量不超过100。

该算法之我的思路

  • 根据题可知应对除-1之外的组合数组的值排序,
    1.从大到小得到数据后,处理数据得到最大效益
    2.从小到大得到数据后,处理数据得到最小效益
  • 算法本身不难,不过需要注意使用的存储变量是否足够计算。我写的算法没有优化空间使用部分,然而大致思路可以参考。

算法展示

#include <iostream>
#include <iomanip>
using namespace std;
double find_min(int Ps[],int Is[],int sign[],double PsIp[],int P,int I,int i,int tempn,double MIN)
{
	int min;
	double minv; 
	//记录最小收益
	while(tempn>0)
	{
		min=0,minv=10.0;
		for(i=0;i<(P*I);i++)
		{
			if(sign[i]>0)//sign[i]==0代表已记录, sign[i]==-1代表不能组合 
			{
				if(minv>PsIp[i])
				{
					minv = PsIp[i];
					min  = i;
				}
			} 
			
		}
		//计算最小收益 
		if(Ps[min/I]<Is[min%I])
		{
			MIN+=Ps[min/I]*minv;
			Is[min%I]=Is[min%I]-Ps[min/I];
			tempn-=Ps[min/I];
			Ps[min/I]=0;
		}else
		{
			MIN+=Is[min%I]*minv;
			Ps[min/I]=Ps[min/I]-Is[min%I];
			tempn-=Is[min%I];
			Is[min%I]=0;
		}
		//处理数据 
		sign[min]=0;
	}
	return MIN;
} 
double find_max(int Ps[],int Is[],int sign[],double PsIp[],int P,int I,int i,int tempx,double MAX)
{
	int max;
	double maxv; 
	//记录最大收益
	while(tempx>0)
	{
		max=0,maxv=0.0;
		for(i=0;i<(P*I);i++)
		{
			if(sign[i]>0)//sign[i]==0代表已记录, sign[i]==-1代表不能组合 
			{
				if(maxv<PsIp[i])
				{
					maxv = PsIp[i];
					max  = i;
				}
			} 
		}
		
		//计算最大收益 
		if(Ps[max/I]<Is[max%I])
		{
			MAX+=Ps[max/I]*maxv;
			Is[max%I]=Is[max%I]-Ps[max/I];
			tempx-=Ps[max/I];
			Ps[max/I]=0;
		}else
		{
			MAX+=Is[max%I]*maxv;
			Ps[max/I]=Ps[max/I]-Is[max%I];
			tempx-=Is[max%I];
			Is[max%I]=0;
		}
		
		//处理数据 
		sign[max]=0;
	}
	return MAX;
} 
int main()
{
	int P,I;
	int Ps[51],Is[51],Psx[51],Isx[51],sign[2501];
	double PsIp[2501],MIN=0.0,MAX=0.0;
	cin>>P>>I;
	int i;
	
	//输出数据 
	int tempn=0,tempx;
	for(i=0;i<P;i++)
	{
		cin>>Ps[i];
		tempn+=Ps[i];
		Psx[i] = Ps[i];
	}
	for(i=0;i<I;i++)
	{
		cin>>Is[i];
		Isx[i]=Is[i];
	}
	for(i=0;i<(P*I);i++)
	{
		cin>>PsIp[i];
		if(PsIp[i]==-1)sign[i]=-1;
		else sign[i]=1;
	}
	
	tempx = tempn;
	MIN = find_min(Ps,Is,sign,PsIp,P,I,i,tempn,MIN);
	
	//恢复Psip[i]未被标记的状态 
	for(i=0;i<(P*I);i++)
	{
		if(PsIp[i]==-1)sign[i]=-1;
		else sign[i]=1;
	}
	
	//记录最大收益
	MAX=find_max(Psx,Isx,sign,PsIp,P,I,i,tempx,MAX);
	
	cout.setf(ios::fixed);
	cout<<fixed<<setprecision(2)<<MIN<<" to "<<MAX; 
	return 0;
}

下文链接:蓝桥杯之未名湖边的烦恼-递归极简版(c++实现)

发布了30 篇原创文章 · 获赞 3 · 访问量 2763

猜你喜欢

转载自blog.csdn.net/weixin_44077556/article/details/104261662
LA