代码及解释
#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;
}