Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <tuple>
- // #include <algorithm>
- using namespace std;
- int n;
- int w[128];
- // 500円玉の枚数が最大, 最小の購入
- typedef tuple < int, int > Coin;
- Coin max(Coin a, Coin b){
- int a_num, a_value;
- int b_num, b_value;
- tie (a_num, a_value) = a;
- tie (b_num, b_value) = b;
- if (a_num > b_num) {
- return a;
- }
- if (a_num == b_num) {
- if (a_value < b_value) {
- return a;
- } else {
- return b;
- }
- }
- return b;
- }
- Coin dp[128][50005];
- // 持ち金(小銭)のコインの種類は関係ない
- Coin solve(const int idx, const int coin) {
- if (idx == n) return make_tuple(0, 0);
- if (dp[idx][coin] != make_tuple(-1, -1)) return dp[idx][coin];
- int num, value;
- Coin ret = solve(idx + 1, coin); // かわない
- int change = 1000 - (w[idx] % 1000); // お釣り整理
- change %= 1000; // お釣りが出ないことを忘れていた
- if (change < 500) { // お釣りが500円未満なら
- if (coin + change >= 500) { // 持ち金と足して500円以上にできるなら
- tie(num, value) = solve(idx + 1, coin + change - 500);
- ret = max(ret, make_tuple(num + 1, value + w[idx]));
- } else { // 持ち金じゃ500円を生成できないとき
- tie(num, value) = solve(idx + 1, coin + change); // お釣り増やしたほうがいい
- ret = max(ret, make_tuple(num, value + w[idx]));
- // 買わないは ret の宣言時やってる
- }
- } else { // お釣りが500円以上の時
- tie(num, value) = solve(idx + 1, coin + change - 500); // 遠慮なく差分をいただく
- ret = max(ret, make_tuple(num + 1, value + w[idx]));
- }
- return dp[idx][coin] = ret;
- }
- int main(int argc, char const *argv[]) {
- while (cin >> n && n) {
- for (int i = 0; i < 128; ++i)
- for (int j = 0; j < 50000; ++j)
- dp[i][j] = make_tuple(-1, -1);
- for (int i = 0; i < n; ++i) cin >> w[i];
- int num, value;
- tie(num, value) = solve(0, 0);
- cout << num << " " << value << endl;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment