找零钱问题

我们知道人民币有1、2、5、10、20、50、100这几种面值。
现在给你n(1≤n≤250)元,让你计算换成用上面这些面额表示且总数不超过100张,共有几种。
比如4元,能用4张1元、2张1元和1张2元、2张2元,三种表示方法。
输入

输入有多组,每组一行,为一个整合n。
输入以0结束。

#include<stdio.h>

#include<stdlib.h>
#include<stdio.h>
#define min(a, b) ((a)<(b)?(a):(b))
int main()
{
    int f[251] = {0}, a[] = {1, 2, 5, 10, 20, 50, 100}, i, j, k;
//f[i]表示金额i共有几种表示方法
    for(i = 0; i < 7; i++)
for(j = min(a[i] * 100, 250); j >= a[i]; j--)
{ //以下代码表示从金额为j开始(依次递减),每个金额相对面币i(一次重复放多张)的可能性有多少种
if(j % a[i] == 0) f[j]++;
for(k = j - a[i]; k > 0; k -= a[i])
 f[j] += f[k];//面值j再减去多张面币i后 还要累加以前的面值为k的种类
}

//f[k]表示a[i]以下的元素组合成k的个数
//例如:当i=1时,a[1]=2,在只有一个2时,剩下的198由i<1的元素组合,当有两个2时,剩下的196也由i<1的元素组合,以此类推;
//f[k]表示a的下标在i以下的元素组合成k的个数;
    for(; scanf("%d", &i), i; printf("%d\n", f[i]));
    return 0;
}
/

#include<stdio.h>
#define M    250
#define N    100
int main()
{
    int f[M + 1][N + 1] = {0};
    int a[] = {1, 2, 5, 10, 20, 50, 100};
    int i, j, k;
    
    for(i = 0; i < 7; i++){
j = a[i];
for(f[j][1] = 1; j <= M; j++)
for(k = 2; k <= N; k++)
 f[j][k] += f[j - a[i]][k - 1];
}


    for(i = 1; i <= M; i++)
    for(j = 1; j <= N; j++)
        f[i][0] += f[i][j];
    
    while(scanf("%d", &i), i) printf("%d\n", f[i][0]);
    
    return 0;

}


//这是自己写的找零钱程序(递归方法)但是只能找200以下的,200以上的会出错,可能是因为占空间不足吧

/*#include<stdio.h>
#include<stdlib.h>
#include<stdio.h>
int get_money(int a[],int k,int t,int money){
int i,j;
int s=0;
if(a[k]*t<money){
s += get_money(a,k+1,t,money-t*a[k]);
for(j=1;(money-t*a[k]+(j*a[k]+money%a[k]))<=money;j++){
s += get_money(a,k+1,t,money-t*a[k]+(j*a[k]+money%a[k]));
}
}
else{
if(money%a[k]==0){ s++;}
else if(2*a[k]>money) return 0;
for(j=1;(j*a[k]+money%a[k])<=money;j++){
s += get_money(a,k+1,t,j*a[k]+money%a[k]);
}
}
return s;
}
void main(){
int a[]={1,2,5,10,20,50,100};
int money = 199,i,s;
s = get_money(a,0,100,money);
printf("%d",s);
getchar();
}

//这个程序也是自己写的,但是这个程序没有纸币限制在100张
#include<stdio.h>
#include<stdlib.h>
#include<stdio.h>
int get_money(int a[],int k,int money){
int i,j;
int s=0;
if(money%a[k]==0){ s++;}
else if(2*a[k]>money) return 0;
for(j=1;(j*a[k]+money%a[k])<=money;j++){
s += get_money(a,k+1,j*a[k]+money%a[k]);
}
return s;
}
void main(){
int a[]={1,2,5,10,20,50,100};
int money = 250,i,s;
s = get_money(a,0,money);
printf("%d",s);
getchar();
}

//以下程序是别人的,不过也没有100张的限制
#include <iostream>  
#include <string>  
using namespace std;  
#define MAX_VALUE   50  
int nexta[20]={0};
int array[] = {1,2,5,10,20,MAX_VALUE};     
int ss = 1;
void SegNum(int nSum, int* pData, int nDepth)  
{  
   
if(nSum < 0)  
        return;  
  
    if(nSum == 0)  
    {  
        for(int j = 0; j < nDepth; j++) 
cout << pData[j] << " "; 
     
cout <<"ss:"<<ss<< endl; 
ss++;
       
        return;  
    }  
  
    int i = (nDepth == 0 ? nexta[0] : pData[nDepth-1]);  
    for(; i <= nSum;)  
    {  
        pData[nDepth++] = i;  
        SegNum(nSum-i,pData,nDepth);  
        nDepth--;  
  
        i = nexta[i];  
    }  
}  
  
void ShowResult(int array[],int nLen)  
{  
    nexta[0] = array[0];  
    int i = 0;  
    for(; i < nLen-1; i++)  
        nexta[array[i]] = array[i+1];  
    nexta[array[i]] = array[i]+1;  
  
    int* pData = new int [MAX_VALUE];  
    SegNum(MAX_VALUE,pData,0);  
    delete [] pData;  
}  
int main()  
{  
    ShowResult(array,sizeof(array)/sizeof(int));  
    system("pause");  
    return 0;  
} */ 

这个程序的结果如下图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值