百钱百鸡算法优化

公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,

用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱。
第一个,最容易想出的算法

public class 百钱百鸡on3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int i, j, k;
	    for( i=0; i <= 100; i++ ){
	        for( j=0; j <= 100; j++ ){
	            for( k=0; k <= 100; k++ ){
	                if( 5*i+3*j+k/3==100 && k%3==0 && i+j+k==100 ){
	                    System.out.println("公鸡有"+i+"只  "+"母鸡有"+j+"只    "+"小鸡有"+k+"只   ");
	                }
	            }
	        }
	    }
	}
}

穷举法,使用三重循环,是最没有效率的算法。时间复杂度O(n^3),循环要执行1000000次
穷举法时间复杂度太高,可以进行适当的优化

===========================================================================

public class 百钱百鸡on2 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int x,y,z,i;
		for(x=0;x<=20;x++){
			i=100-x*5;             //缩小了i的范围,减少了遍历
			for(y=0;y<=i/3;y++){	 
				z=3*(i-3*y);        //Z直接可以求出来,不需要在用一个循环
				if(x+y+z==100){
					System.out.println("公鸡有"+x+"只  "+"母鸡有"+y+"只    "+"小鸡有"+z+"只   ");
				}
			}
		}
	}

}

小鸡的数量可以直接通过母鸡的数量和公鸡的数量算出来,算法简化成了二重循环。
同时我们也根据题意,限定了每层循环执行的次数,不再是无脑的100次
算法的时间复杂度为O(n^2)

==========================================================================
算法其实还可以继续优化成O(n),通过数学的方法,我们可以列出题目的方程组,设公鸡为x,母鸡为y,小鸡为z
在这里插入图片描述
我们把3x(1)-(2),得到
在这里插入图片描述
在这里插入图片描述
再把y的式子带入到(2),得到
在这里插入图片描述
然后,我们可以使用高中数学中的换元法,让k=x/4,如下在这里插入图片描述
然后,根据题目的定义域,列出方程
在这里插入图片描述
最后算出k的范围是0-25/7,也就是0到3点多

public class 百钱百鸡on1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        int x=0, y=0, z=0;
        for (int k = 1; k <= 3; k++){
            x = 4 * k;
            y = 25 - 7 * k;
            z = 75 + 3 * k;
            System.out.println("公鸡有"+x+"只  "+"母鸡有"+y+"只    "+"小鸡有"+z+"只   ");
        }
	}

}

最后,算法被优化成了O(n),并且整个循环只要执行3次。
从一开始的穷举法需要执行1000000次,再到现在的只需要执行3次。
算法的改变带了时间复杂度的巨大变化。
不得不说,一开始想到这个方法的人是真的厉害

============================================================================
参考博客:百钱百鸡-经典算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值