百钱买百鸡算法的扩展,动态for循环构造收藏

百钱买百鸡算法的扩展,动态for循环构造收藏
    CSDN上 有人出了一个题,有三种物品的价格如下:1.2,3.4,6.2。现在已知一个总价14.2,要求三种物品各取多少个时其求和的总价与给定的总价相等。这其实就是典型的百钱买百鸡问题。只不过不一样的是,要求构造的程序不限制物品及其价格的数量,即可能是3种,4种或者几十上百种物品及其价格。
    对于典型的百钱百鸡问题,由于知道是三种价格,所以用三个for循环来穷举所有可能,再求和看与给定的总价是否相等来找到所有的解。但在本题中,由于物品种数是变化的,所以不能采用固定的for循环来完成,但又需要同样采用穷举的思路,所以必须对算法有所改进。
    设有n个物品a1, a2, ..., an,对应n个价格p1, p2, ..., pn,而要求的总价格是P,即a1*p1+a2*p2+...+an*pn=P。我们依然可以利用百钱百鸡问题的思路来穷举,即:
    设i=1, 2, ..., n
    令a(i)=0, 1, 2, ..., P/p(i)
    对a(i)*p(i)求和,如果结果等于P,则找到一个答案。
    不过,由于不能确定循环总数,我们只能推算每个a(i)的值。思路是现令a(i)等于0,再令a(n)=1, 2, ..., P/p(n)。从a(n)反推前面的a(i),即由a(i)==>a(i-1),当a(i)大于P/p(i)时,令a(i)=0,a(i-1)=a(i+1),直到a(0)>P/p(0)。
   当然,为了提高效率,减少循环次数,我们还可以修改a(i)>P/p(i)的条件,以剔出显然不可能的组合,即先计算a(0)*p(0)+a(1)*p(1)+...+a(i-1)*p(i-1)=Pt,若a(i)>(P-Pt)/p(i)时,则可以停止a(i)的递增,进行a(i)初始化和a(i-1)的递推了。这样,算法如下:
1)令a(i)=0,其中,i=0, 1, 2, ..., n
2) 当a(0)<P/p(0),进行下列步骤,否则,退出
3)求total=a(0)*p(0)+a(1)*p(1)+...+a(n)*p(n)
4)若total=P,则输出结果
5)a(n)=a(n)+1
6)令j=n, n-1, ..., 0,执行到步骤8)
7)求Pt=a(0)*p(0)+a(1)*p(1)+...+a(j-1)*p(j-1)
8)若a(j)>(P-Pt)/p(j),则a(j)=0,a(j-1)=a(j-1)+1
9)返回步骤2)
    下面是相应算法的Java程序:

public class test {
    public static void main(String[] arg) {
        double p[]={1.2,6.2,3.4,2.3};
        int a[]=new int[p.length],loop=0;
        double price=16.5;
        for(int i=0; i<p.length; i++) a[i]=0;
        while(a[0]<price/p[0]) {
            double total=0;
            loop++;
            for(int i=0; i<a.length; i++) total+=a[i]*p[i];
            if(total==price) {
                for(int i=0; i<a.length-1; i++)
                    System.out.print(a[i]+"*"+p[i]+"+");
                System.out.println(a[a.length-1]+"*"+p[p.length-1]+"="+price);
            }
            a[a.length-1]++;
            for(int i=a.length-1; i>0; i--) {
                total=0;
                for(int j=0; j<i-1; j++) total+=a[j]*p[j];
                if(a[i]>(price-total)/p[i]) {
                    a[i]=0;
                    a[i-1]++;
                }
            }
        }
        System.out.println("Total Num:"+loop);
    }
}

下面是运行结果:
0*1.2+1*6.2+1*3.4+3*2.3=16.5
1*1.2+1*6.2+2*3.4+1*2.3=16.5
8*1.2+0*6.2+0*3.4+3*2.3=16.5
9*1.2+0*6.2+1*3.4+1*2.3=16.5
Total Num:400

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/JianZhiZG/archive/2007/03/08/1524334.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
百钱买百鸡问题是一个经典的数学问题,可以用循环方法在Python中求解。根据题目给出的条件和分析,我们可以使用三层嵌套循环来解决这个问题。 首先,我们需要设定公鸡的数量在0到20之间进行循环,可以使用如下的代码: ``` for cock in range(0, 21): ``` 其中,cock表示公鸡的数量。 接下来,在每个公鸡数量的循环中,我们需要再次进行两层嵌套循环,分别表示母鸡和小鸡的数量的范围。在这里,我们需要注意到母鸡的数量是受到公鸡数量限制的,而小鸡的数量受到公鸡和母鸡数量的限制。 完整的代码如下: ``` for cock in range(0, 21): for hen in range(0, 34): for chicken in range(0, 101): if cock + hen + chicken == 100 and cock * 5 + hen * 3 + chicken / 3 == 100: print("公鸡数量:", cock, "母鸡数量:", hen, "小鸡数量:", chicken) ``` 在这段代码中,我们通过判断公鸡、母鸡和小鸡的数量是否满足题目给出的条件,如果满足则打印出对应的数量。 这样,我们就可以得到所有可能的买鸡方案,并统计有多少种买法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Python——解决百元买百鸡问题](https://blog.csdn.net/ayddyn/article/details/130666677)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [100个python算法超详细讲解:百钱百鸡](https://blog.csdn.net/tysonchiu/article/details/124751315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值