贪婪法解决大小油壶问题

//------------------------------------------------------------------------
//大小油壶问题
//油店招工,出题考试:有一缸油,但仅有两个油壶,大的可装11升,小的可装7升,
//现在要按1升油分装,怎么分呢?

//思路:如果到了某一步,油壶为空,可以再取油;油壶为满可以倒掉,也可以转到另一个壶中
#include <stdio.h>
#include <windows.h>

#define BIG 11   //大壶容量
#define SMALL 07  //小壶容量
#define RESULT 01  //要求的结果RESULT<BIG
#define MAX_STEPS 100 //定义最大步数,避免无解时无限循环

//其实非递归更加有效
//使用这两个数组只是为了知道中间的过程
int Big[MAX_STEPS];  //记录每一步的大壶中的油
int Small[MAX_STEPS]; //记录每一步的小壶中的油
int bottle(int n)
{ if(n>=MAX_STEPS)
  return false; //未找到解,试试把MAX_STEPS定义为更加大的值

 if(Big[n]==RESULT || Small[n]==RESULT)
  return n;  //已经找到解,返回解的步数

 if(Small[n]==0)//小壶是空的
 { Small[n+1]=SMALL;//小壶加满
  Big[n+1]=Big[n];//大壶不变
 } else if(Big[n]<BIG)//大壶没有满
 { int x=min(BIG-Big[n],Small[n]);//大壶是有容量限制的
  Small[n+1]=Small[n]-x;//小壶->大壶
  Big[n+1]=Big[n]+x;//
 } else//大壶满了
 { Small[n+1]=Small[n];//小壶不变
  Big[n+1]=0;//大壶清空
 }
  
 return bottle(n+1);//简单递归
};


void test()
{ Big[0]=0,Small[0]=0;//设定初始状态
 int r=bottle(0);

 for(int i=0;i<=r;++i)
 { printf("第%2d步:大壶%2d,小壶%2d/n",i,Big[i],Small[i]);
 }
};

 

//注意:结果并非是最优解,而是贪婪解
//因为解法中只是将小壶作为主动壶,而大壶作为辅助壶,也就是小壶可直接取油,而大壶
//总是从小壶中取油,事实上大壶也可直接取油,将算法略作调整即可
//更简单的,将BIG和SMALL定义对调即可得到以大壶为主动壶时的解。
//看起来是有点别扭,似乎定义成FIRST和SECOND更恰当,这个就留给你去做吧。


//深入一下
//问题实际上就是求二元一次方程a*x-b*y=c的整数解,其中a,b为两个油壶的容量,c是需要的容量
//x,y就是要求的未知数,x代表倒进的次数,y代表倒出的次数,x>=0,y>=0
//a,b设置不同结果当然不同,求出x,y就知道具体过程了

 

//如果是有三个油壶
//问题实际上就是求三元一次方程a*x+b*y+c*z=d的整数解
//不过这里x,y,z可以是负整数了,为正代表倒进,为负代表倒出

 

//类似可解决更多个油壶的问题

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值