蛮力法
蛮力法通常在算法题中经常用到,也称为暴力枚举,其核心为遍历,即通过列举所有可能的情况,从而得到合适的解。从人的思维角度来看,其实这是一种非常笨的方法。
优点
- 通俗易懂,能后很好的模拟人的思维
- 几乎能够解决所有可计算领域的问题
缺点
- 需要遍历出现的每一种情况,算法时间开销较大
- 适合解决问题规模较小的问题,一旦规模较大,算法时间性能将大大下降
百元买百鸡
这是一个非常经典的循环问题,相信大家在刚学习编程时都会接触到,通俗来讲,就是:
你有100元,现有公鸡5元一只,母鸡3元一只,小鸡1元3只,那么你如何分配所买鸡的种类从而使得鸡数为100且100元恰好花光!
传统暴力枚举
传统思路:我直接枚举每一种方案,只要符合我设置的条件
//假设公鸡数x,母鸡数y,小鸡数z
①x+y+z==100;
②5x+3y+z/3==100
此种情况下,我所得到的各鸡的数量一定是符合要求的
void Chicken(
int x,y;z;
int count-0;
for(x=0;x<=100;x++)//公鸡
{
for (y=0;y<=100;y++)//母鸡
{
z=100-x-y;//小鸡
if((z%3==0)&&(5*x+3*y+z/3==100))//设置条件
{
count++;//解的个数
count<<"公鸡:"<<x<<"母鸡:"<<y<<"小鸡:"<<z<<endl;
}
}
}
if(!count)
cout<<"无解"<<endl;
减少无用枚举
再来想,那么每种鸡的数量是不是有个最大值呢?
公鸡5元,我买再多,最多买20只
母鸡3元,最多33只
小鸡=100-公鸡-母鸡
也就是说,各鸡数量不可能超过这个最大值,若超过,一定是不满足条件的,可以直接舍去!!!
void Chicken(
int x,y;z;
int count-0;
for(x=0;x<=20;x++)
{
for (y=0;y<=33;y++)
{
z=100-x-y;
if((z%3==0)&&(5*x+3*y+z/3==100))
{
count++;
count<<"公鸡:"<<x<<"母鸡:"<<y<<"小鸡:"<<z<<endl;
}
}
}
if(!count)
cout<<"无解"<<endl;
最优解法
此处主要运用数学知识来进行简化算法,可见数学在算法中的地位!
根据关系式:
x+y+z=100
5x+3y+z/3=100
可得
①0<=x<=20
②0<=y<=33(必为整数)
所以可推出③47<=z<=100;
根据数学知识转化
3②-1=>*b=25-(7/4)a
由于鸡的数量都是大于等于0的整数,所以a必须是4得倍数。假如num是一个大于等于0的整数则a可表示为4num;则b可表示为25-7num,c可表示为75+3*num
我们根据0<=a<=20;得到num得范围为0<=num<=5;
根据0<=b<=33;得到num得范围为0<=num<=3;
根据c;得到num得范围为0<=num<=8;
所以num的最终范围为0<=num<=3;
for(int num=0;num<=3;++num){
cout<<"公鸡:"<<4*num;
cout<<"母鸡:"<<25-7*num;
cout<<"小鸡:"<<75+3*num<<endl;
}
此解法四次遍历即可搞定,大大降低了时间复杂度,也可以从中看到数学的魅力!!!