原链接:http://www.cnblogs.com/m6830098/p/3405647.html
1 百钱买百鸡问题:有一个人有一百块钱,打算买一百只鸡。到市场一看,公鸡一只3元,母鸡一只5元,小鸡3只1元,试求用100元买100只鸡,各为多少才合适?
策略:
根据题意我们可以得到方程组:
3X + 5Y + Z/3 = 100;
X + Y + Z = 100;
(100 > X,Y,Z > 0, Z%3 == 0),根据这两个公式,我们可以写出最为简单的代码,一一列举所有解进行枚举
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int x,y,z;
for(x=0;x<100;x++)
for(y=0;y<100;y++)
for(z=0;z<100;)
{
if(x+y+z==100&&3*x+5*y+z/3==100)
{
cout<<x<<" "<<y<<" "<<z<<endl;
}
z+=3;
}
return 0;
}
运行结果:
4 12 84
11 8 81
18 4 78
25 0 75
然而我们可以根据已知条件来进行优化代码,减少枚举的次数:
三种鸡的和是固定的,我们只要枚举二种鸡(x,y),第三种鸡就可以根据约束条件求得(z = 100 - x - y),这样就缩小了枚举范围。
另外我们根据方程特点,可以消去一个未知数,得到下面
4X + 7Y = 100;
X + Y + Z = 100;
(X,Y,Z > 0, Z%3 == 0),=>> 0 <= x < = 25因此代码可以优化为下面这样子:
#include <iostream>
using namespace std;
int main()
{
int x,y,z;
for(x=0;x<=25;x++)
{
y=100-4*x;//独特的地方
if(y%7==0&&y>=0)//独特的地方
{
y/=7;//独特的地方
z=100-x-y;
if(z%3==0&&3*x+5*y+z/3==100)//3*x+5*y+z/3==100不加也行这个公式
cout<<x<<" "<<y<<" "<<z<<endl;
}
}
return 0;
}
运行结果同上。
采用枚举的方法进行问题求解,需要注意3个问题:
- 简历简单数学模型,数学模型中变量数量尽量少,它们之间相互独立。这样问题解的搜索空间的维度就小,反应到程序代码中,循环嵌套的层次就会少。我们上面从3维优化到一维。
- 减少搜索的空间。利用已有知识,缩小数学模型中各个变量的取值范围,避免不必要的计算。反应到程序代码中,循环体被执行的次数少
- 采用合适的搜索顺序。对搜索空间的遍历顺序要与数学模型中的条件表达式一致。