渴婴问题编程

本文探讨了一位聪明的小婴儿如何通过最大化满意度选择多种饮料来解渴的问题。通过定义满意度值并考虑每种饮料的可用量,文章提出了一种算法解决方案,旨在找到最佳的饮料组合以满足婴儿的特定需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 有一个非常渴的、聪明的小婴儿,她可能得到的东西包括一杯水、一桶牛奶、多罐不同种类的果汁、许多不同的装在瓶子或罐子中的苏打水,即婴儿可得到n 种不同的饮料。根据以前关于这n 种饮料的不同体验,此婴儿知道这其中某些饮料更合自己的胃口,因此,婴儿采取如下方法为每一种饮料赋予一个满意度值:饮用1盎司第i 种饮料,对它作出相对评价,将一个数值si 作为满意度赋予第i 种饮料。

    通常,这个婴儿都会尽量饮用具有最大满意度值的饮料来最大限度地满足她解渴的需要,但是不幸的是:具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。设ai是第i 种饮料的总量(以盎司为单位),而此婴儿需要t 盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?

    设各种饮料的满意度已知。令xi 为婴儿将要饮用的第i 种饮料的量,则需要解决的问题是:

    找到一组实数xi(1≤i≤n),使n?i=1 si*xi 最大,并满足:(n?i=1 xi) =t 及0≤xi≤ai 。
    需要指出的是:如果(n?i=1 ai) < t,则不可能找到问题的求解方案,因为即使喝光所有的饮料也不能使婴儿解渴。
    对上述问题精确的数学描述明确地指出了程序必须完成的工作,根据这些数学公式,可以对输入/ 输出作如下形式的描述:

    输入:n,t,si ,ai(其中1≤i≤n,n 为整数,t、si 、ai 为正实数)。
    输出:实数xi(1≤i≤n),使n?i=1 si*xi 最大且(n?i=1 xi)=t(0≤xi≤ai)。

    在这个问题中,限制条件是(n?i=1 xi)=t 且0≤xi≤ai,1≤i≤n。而优化函数是n?i=1 si*xi 。任何满足限制条件的一组实数xi 都是可行解,而使n?i=1 si*xi 最大的可行解是最优解。

// keying problem.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <iostream>
#include<malloc.h>
using namespace std;
class BeverageNode//每种饮料的参数,包括名字,满意度,总量
{
	friend  class Beverage;
private:
	string   beveName;
	int baby_satisfaction;
	int beve_quantity_sum;
    BeverageNode * link;
};
class  Beverage //用链表来保存各饮料的参数
{
public:
	
	~Beverage();
	 Beverage( );
	 void input();//各饮料参数的客户输入
     void satisfaction_sort();//饮料满意度从大到小排序,链表的排序
	 int workout();
	 void output();
private:
	int bevetypesum;//饮料的种类
	int baby_requirementsum;//婴儿所需饮料的总量
	BeverageNode * first;
};
Beverage::Beverage()
{
	this->bevetypesum=0;
	this->baby_requirementsum=0;
	first=new BeverageNode;
	first->link=NULL;
	
}
Beverage::~Beverage()
{
	BeverageNode *next;
	while (first)
	{
		next=first->link;
		delete first;
		first=next;
	}
	
}
void Beverage:: input()
{
	cout<<"请输入饮料的种类"<<endl;
	cin>>this->bevetypesum;
	cout<<"请输入婴儿所需饮料总量:"<<endl;
	cin>>this->baby_requirementsum;
	cout<<"请输入"<<bevetypesum<<"种饮料"<<endl;
	//first=(class BeverageNode *)malloc(sizeof(BeverageNode));
	BeverageNode * current=this->first;
	BeverageNode * middle;
	//this->first=current;
	for(int i=1;i<this->bevetypesum+1;i++)
	{
		middle=new BeverageNode;
		cout<<"请依次输入beveName、baby_satisfaction、beve_quantity_sum"<<endl;
		cin>>current->beveName;
		cin>>current->baby_satisfaction;
		cin>>current->beve_quantity_sum;
		if(i==this->bevetypesum)
		{
			current->link=middle;
			current->link=NULL;
			return;
		}
		else
		{
		    current->link=middle;
		    current=current->link;
		}
	}
}
void Beverage::satisfaction_sort()//链表的冒泡排序,开始是有界限的,把链表按满意度从大到小的顺序排列
{
	BeverageNode * current1=first;
	BeverageNode * current2=current1;
	BeverageNode * change=new BeverageNode;
	int flag=1;
	while(current1!=NULL&&flag)
	{
     flag=0;
	 while (current2!=NULL)
	 {
		 if(current2->link==NULL)
		 {
			 change->beveName=current2->beveName;
			 change->baby_satisfaction=current2->baby_satisfaction;
			 change->beve_quantity_sum=current2->beve_quantity_sum;
			 current2->baby_satisfaction=current1->baby_satisfaction;
			 current2->beveName=current1->beveName;
			 current2->beve_quantity_sum=current1->beve_quantity_sum;
			 current1->baby_satisfaction=change->baby_satisfaction;
			 current1->beveName=change->beveName;
			 current1->beve_quantity_sum=change->beve_quantity_sum;
		 }
		 else
		 if(current2->baby_satisfaction>current2->link->baby_satisfaction)
		 {
			 change->beveName=current2->link->beveName;
			 change->baby_satisfaction=current2->link->baby_satisfaction;
			 change->beve_quantity_sum=current2->link->beve_quantity_sum;
			 current2->link->baby_satisfaction=current2->baby_satisfaction;
			 current2->link->beveName=current2->beveName;
			 current2->link->beve_quantity_sum=current2->beve_quantity_sum;
			 current2->baby_satisfaction=change->baby_satisfaction;
			 current2->beveName=change->beveName;
			 current2->beve_quantity_sum=change->beve_quantity_sum;
			 
			 if(flag==0)
				 flag=1;
		 }
		  current2=current2->link;
		
	 }
	 current1=current1->link;
	 current2=current1;
	}
}
int Beverage::workout()//求解xi;
{
	satisfaction_sort();//对链表先排序;
	int i=0;//统计需多少种类的饮料
	int sum=0;//各饮料数量的总量统计
	BeverageNode *current=first;
	while(current)
	{
		i++;
		sum+=current->beve_quantity_sum;
		if(sum>=this->baby_requirementsum)
		{
			current->beve_quantity_sum-=sum-this->baby_requirementsum;
			return i;
		}
		else
			if(current->link==NULL)
			{
				return -1;
			}
			else

		    {
			    current=current->link;
		    }
	}

}
void Beverage::output()
{    
	BeverageNode *current=first;
	while(current!=NULL)//输出未排序的链表
	  {
		cout<<current->beveName<<"  "<<current->baby_satisfaction<<"  "<<current->beve_quantity_sum<<endl;
		current=current->link;
	  }
	current=first;
	int i=workout();
	int j=0;
	
	if(i==-1)
	{
		cout<<"饮料总量不能解决婴儿渴的问题"<<endl;
	}
	else
	{
		while(current)//输出婴儿所需的饮料数量及种类
	  {
		j++;
		cout<<current->beveName<<"  "<<current->baby_satisfaction<<"  "<<current->beve_quantity_sum<<endl;
		current=current->link;
		if(j==i)
		{
			return;
		}
	  }
	}
	
}
void main()
{
	Beverage be;
	be.input();
	be.output();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值