公鸡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次。
算法的改变带了时间复杂度的巨大变化。
不得不说,一开始想到这个方法的人是真的厉害
============================================================================
参考博客:百钱百鸡-经典算法