专题一 · 1005

代码及解释

#include <iostream>
#include <cstdlib>
#include <algorithm>


//做这道题的时候想多了……
//算最小值的时候很简单,
// 
//但是算到最大值的时候,陷入了深深的沉思……
//
//1)穷举会超时啊……
//
//2)先从小面额算起,但是前面决策会对后面产生影响,
//   DP可以做,但是方程不好写。 不会一开始就有动规把……
//
//3)在给定约束条件下求多项式极值,这不是拉格朗日方程吗……
//
//然后我就开始动手,用纯数学的方法去写。
//但是写到一半发现太复杂了……
//想了一个中午,突然反应过来:
//钞票数目最多不就是剩下钞票最少么……
//然后把上面的一复制、修改,果断AC……
// 
//最大的教训就是,
//考虑问题的时候一定要深入考虑,
//不要太着急。


int main() {

    const int SIZE= 1000000 + 1;
    const int v[5] = {1,5,10,50,100};

    int N;
    std::cin >> N;

    for (int k = 0; k < N; k++) {

        int num[5];
        int P;

        //总钱数
        int Q = 0;

        //最小值,最大值
        int ans1 = 0, ans2 = 0;

        std::cin >> P;
        for (int i = 0; i < 5; ++i) {
            std::cin >> num[i];
            Q += num[i] * v[i];
            ans2 += num[i];
        }

        //剩下的钞票面额,用来算 ans2
        //因为钞票最多 = 剩下的钞票最少
        Q -= P;

        //从大钱开始算
        for (int i = 4; i >= 0; --i) {
            int count = std::min(num[i], P/v[i]);
            P -= count * v[i];
            ans1 += count;
        }

        for (int i = 4; i >= 0; --i) {
            int count = std::min(num[i], Q/v[i]);
            Q -= count * v[i];
            ans2 -= count;
        }

        //全部检查过了还是没能兑换成功
        if(P){
            std::cout << "-1 -1" << std::endl;
            continue;
        }

        std::cout << ans1 << ' ' << ans2 << std::endl;
    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值