有限零钱找补 算法

运用了贪心算法,解决了有限零钱分解问题

采用算法为双循环贪心算法加五分法(原创)。

当输入现有零钱为 50  20时

当采用贪心算法单循环是80无法分解,所以我用了多循环贪心算法。

接着在测试110时,也无法分解,所以嵌套了一次贪心算法。

然后我测试了30之240都正常

     当输入现有零钱为10,5 ,2,时

输入11是出现的找补方案为,10的一张,5元的-1张,2元的3张。这明显不对。

我考虑到了用任何数除以5后是偶数,2就能有找补的。若是奇数时,把补五的数量减一

,把2加3张。让后在种数里减去2的总额。剩下的用贪心算法解决。

  因为使用了贪心算法,并不是整体最优解,所以缺少普遍性。由于时间有限,只进行了小范围的测试,改正了发现的问题。

#include<iostream>

using namespace std;
int N,one,two,five,ten,tew,fity;
int *parvalue1;
int function(int *cion,int sum);
int wufenfa(int *cion,int sum);
int main()
{
int kinds,i,sum;
i=0;
int parvalue[10]={0};
cout<<"现有的零钱输入后以0结束"<<endl;
do{
cin>>kinds;
parvalue[i]=kinds;
i++;
if(kinds==1)
{
one=1;
continue;
}
else if(kinds==2)
{
two=2;
continue;
}
else if(kinds==5)
{
five=5;
continue;
}
}while(kinds!=0);
parvalue1=
new int[i-1];
N=i-1;//记录零钱的种数
for(int j=0;j<i-1;j++)
{
parvalue1[j]=parvalue[j];
}
cout<<"输入将要分解的钱"<<endl;

char flag;
if(two&&five)
{

do{
cin>>sum;
wufenfa(parvalue1,sum);
 cin>>flag;
}while(flag=='y');
}
else {
do{
cin>>sum;
 function(parvalue1,sum);
 cin>>flag;
}while(flag=='y');
}

return 0;

}
int function(int *cion,int sum)

if(sum>1&&N!=0)
{
int flag=0;
int *count=new int[N];

int i;//记录最大钞票的位置
for(i=0;i<N;i++)
{
if(sum>=cion[i])
{
break;
}
}
int sum1=sum;
/********************************************/
for(;i<N;i++)

cout<<"sum1="<<sum1<<endl;
sum=sum1;
            int h=i;
for(int r=0;r<N;r++)
{
count[r]=0;
}
while(sum>0&&h<N)
{
cout<<"h="<<h<<endl;
if(sum>=cion[h])
{
cout<<"cion="<<cion[h]<<endl;
sum-=cion[h];
count[h]++;
flag++;
cout<<"flag="<<flag<<endl;

else
{
h++;
}
if(sum==0)
{
cout<<"fjjjf"<<endl;
break;
}
}
if(sum==0)break;

if(flag>1)

cout<<"使用"<<endl;
   h=h-2;
cout<<"h="<<h<<endl;
flag--;
count[h]--;
sum+=cion[h];
cout<<"sum="<<sum<<endl;
h++;
while(sum>0&&h<N)
{
cout<<"h="<<h<<endl;
if(sum>=cion[h])
{
cout<<"cion["<<h<<"]="<<cion[h]<<endl;
sum-=cion[h];
count[h]++;

else
{
h++;
}
if(sum==0)
{
cout<<"fjjjf"<<endl;
break;
}
}


}


if(sum==0)break;
}
/*****************/
cout<<"sum"<<sum<<endl;
if(i==N&&sum!=0)
{
cout<<"没有解"<<endl;
return 0;
}
else
{
for(int j=0;j<N;j++)
{
if(count[j]!=0)
{
cout<<"可以找回"<<cion[j]<<"元的"<<count[j]<<"张"<<endl;
}
}


}


}
return 0;
}
int wufenfa(int *cion,int sum)


{
         int fivecount=sum/5;
cout<<"fivecount="<<fivecount<<endl;
int i=sum%5;
int twocount=i/2;
int j=i%2;
int sum1,sum2;
if(j==0)
{
sum1=fivecount*5;
cout<<"sum2"<<sum2<<endl;
function(cion,sum1);

cout<<"可以找回2元的"<<twocount<<endl;
}
else{
fivecount--;
twocount+=3;
sum1=fivecount*5;


function(cion,sum1);
 if(twocount!=0)
cout<<"可以找回2元的"<<twocount<<endl;


}
return 0;


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值