背包问题(旅游记得带零钱)

Description卖方:这件商品14元买方:给你20元卖方:不好意思,我的零钱不够买方:好吧,这是15元,剩的当小费当到一个地方旅游时,如果你买东西的地方不支持信用,带零钱还是非常有用的。特别是有时候卖方没有零钱,如果你没有刚好的钱,你需要支付比卖价多一点。当然你想付尽量少的钱(至少是商品价值的钱)。并且,当支付最少钱的时候,也最好是支付的硬币的数量最少。Input第一行包含一个整数表示测试数据的组数。每组测试数据每一行包含一个整数,表示你需要付的钱数,钱数不超过10000元。接下来包含
摘要由CSDN通过智能技术生成

Description

卖方:这件商品14元
买方:给你20元
卖方:不好意思,我的零钱不够
买方:好吧,这是15元,剩的当小费

当到一个地方旅游时,如果你买东西的地方不支持信用,带零钱还是非常有用的。特别是有时候卖方没有零钱,如果你没有刚好的钱,你需要支付比卖价多一点。

当然你想付尽量少的钱(至少是商品价值的钱)。并且,当支付最少钱的时候,也最好是支付的硬币的数量最少。

Input

第一行包含一个整数表示测试数据的组数。每组测试数据每一行包含一个整数,表示你需要付的钱数,钱数不超过10000元。接下来包含一个整数n,表示你所拥有的钱的数量,n最多是100,接下来的n行每行一个整数,表示你有的每个硬币的面值,注意钱的面值可以是任意的,不和我们现在用的面值一样,钱的面值不超过10000元。

Output

对每组测试数据,在一行上输出两个整数:需要支付的钱数和数量。

Sample Input

1
1400
3
500
1000
2000

Sample Output

1500 2

基本思路

数组a用来存储钱的种类,从a[1]开始输入,a[0]置成0,sum为钱数总和。因为要输出最少的钱和最少的张数,当a[i]出现price时,直接输出a[i],钱的张数为1。
如果a[i]中没有和price相等的值,用数组dp。dp[0][0]置成1,数组第一行从dp[0][1]开始,附成0,数组第一行从1到num,dp[i][0]都赋成1。从头开始查找,如果j<a[i],dp[i][j]=dp[i-1][j];当j>=a[i]的时候,说明出现可以支付的钱,运用公式dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]]。
开辟数组b用来存放dp数组中值为1的数。然后对数组b中的值进行排序,从小到大。当b中出现第一个值比price大的数,他就是要找的最少的钱数,将其输出。用count来记录钱的张数,如果输出的钱数比输入的a[i]中的值大,证明一张a[i]不够支付,count就要+1。如果数组b中最大的数都比price小,说明没有足够的钱支付。

注意:数组要开的足够大!!!!

运行代码

#include<iostream>
#include<malloc.h>
 
using namespace std;
int dp[101][30400];
int b[20001];
int a[101];
int main()
{
   
    int n,price,num,i,sum=0,k=0,m=0,j,count=0,p;
    cin>>n;
    while(n--)
    {
   
        cin>>price>>num;
        //if(price>100)
//       int *a=new int[num];
        a[0]=0;
        sum=0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值