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;
}