细说蛮力法(一)

蛮力法

蛮力法通常在算法题中经常用到,也称为暴力枚举,其核心为遍历,即通过列举所有可能的情况,从而得到合适的解。从人的思维角度来看,其实这是一种非常笨的方法。

优点

  • 通俗易懂,能后很好的模拟人的思维
  • 几乎能够解决所有可计算领域的问题

缺点

  • 需要遍历出现的每一种情况,算法时间开销较大
  • 适合解决问题规模较小的问题,一旦规模较大,算法时间性能将大大下降

百元买百鸡

这是一个非常经典的循环问题,相信大家在刚学习编程时都会接触到,通俗来讲,就是:

​ 你有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;
}

此解法四次遍历即可搞定,大大降低了时间复杂度,也可以从中看到数学的魅力!!!

猜你喜欢

转载自blog.csdn.net/pipihan21/article/details/129413146