练习基础题《三》

Q:

公司发了某市廛的购物券1000元,限制只能购买店中的m种商品。每种商品的价格分别为m1,m2,…,请求法度列出所有的正好能花费完该购物券的不合购物办法。


法度输入:


第一行是一个整数m,代表可购买的商品的种类数。


接下来是m个整数,每个1行,分别代表这m种商品的单价。


法度输出:


第一行是一个整数,默示共有几许种规划


第二行开端,每种规划占1行,默示对每种商品购买的数量,中心用空格分隔。


例如:


输入:


2


200


300


则应输出:


2


2  2


5  0


输入:


2


500


800


则应输出:


1


2  0


 A:

    自己不会做,看网上的代码理解好长时间才明白的。。。囧、、

 思路:

  可定义一个商品的结构体,包括价格,数量,及最大可购买量。

然后循环,假如第一件商品最大可购买5,第二件最大可购买4,第三件最大可购买3,则共有6*5*3=90中可能吧

难点是怎样控制循环,。首先第一件物品的购买数量从零开始每次自加一,直至到最大数量,这是其他种类的商品购买数量均为零,在清零,同时下一物品的购买数量加一,其他的不变,可用递归来控制下一物品的情况。

PS:思路抄袭别人的,,此题涉及到贪心算法。。。

Code:

#include<iostream>
using namespace std;
#define MAX 100
#define Total 1000
struct item
{
       int price;
       int count;
       int maxSize;
};
int main()
{
    int kind,i,j,sum=0;
    cout<<"请输入物品的种类"<<endl; 
    cin>>kind;
    item a[MAX];
    void F(item *);
    cout<<"请输入每种物品的价格"<<endl; 
    for(i=0;i<kind;++i)
    { 
       cin>>a[i].price;
       a[i].count=0;
       a[i].maxSize=Total/100;
    }
    i=0;
    while(a[kind-1].count<a[kind-1].maxSize)
    {
        (a[0].count)++; 
         F(&a[0]);
         for(j=0;j<kind;++j)
         sum+=a[j].price*a[j].count;            //艹蛋啊,,,+号看成*号浪费哥一天的时间啊 。。。。
         if(sum==Total)
         {
           for(int k=0;k<kind;++k)
           cout<<a[k].count<<" ";
           cout<<endl;
           sum=0;
         }
         else
         sum=0;
    }
    system("pause");
    return 0;
}
   void F(item *a)
   {
        int i=0;
        if((a+i)->count>(a+i)->maxSize)
        {
           (a+i)->count=0;
           ++((a+(++i))->count);
           F(a+i);  //判断其下一元素的count是否达到maxSize
        }
        else
        return ;
   }                                 
    PS:永远不要怀疑程序的执行错误,是你的代码有问题!

解法2:

 利用递归回溯

#include<iostream>
using namespace std;
int method[50][50];
int cost;
int price[50];
int coun[50];
int sln;
int gm;
    void F(int m)
    {
         int i;
         if(cost==1000)
         {
           for(i=0;i<gm;++i)
            method[sln][i]=coun[i];
            sln++;
            return ;
         }
         if(cost>1000||m<0)
         return ;
         ++coun[m];
         cost+=price[m];
         F(m);
         --coun[m];
         cost-=price[m];
         F(m-1);
    }
    void Output()
    {   int m,n;
         for(m=0;m<sln;++m)
         {
            for(n=0;n<gm;++n)
            cout<<method[m][n]<<" ";
            cout<<endl;
         }
    }
    
int main()
{
    int kind;
    cin>>kind;
    gm=kind;
    for(int k=0;k<kind;++k)
    cin>>price[k];
    F(kind-1);
    Output();
    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值