[hihoCoder] 买零食

http://hihocoder.com/contest/hiho139/problem/1?sid=992251

描述

小Ho很喜欢在课间去小卖部买零食。然而不幸的是,这个学期他又有在一教的课,而一教的小卖部姐姐以冷若冰霜著称。第一次去一教小卖部买零食的时候,小Ho由于不懂事买了好一大堆东西,被小卖部姐姐给了一个“冷若冰霜”的眼神,食欲都下降了很多。

从那以后,小Ho就学乖了,去小卖部买东西只敢同时买3包以内的零食,并且价格加起来必须是5的整数倍,方便小卖部姐姐算价格。

但是小Ho不擅长计算,所以他把小卖部里所有零食的价格以及他对这个零食的渴望度都告诉了你,希望你能够帮他计算出在不惹恼小卖部姐姐的前提下,能够买到零食的渴望度之和最高是多少?

输入

每个输入文件包含多组测试数据,在每个输入文件的第一行为一个整数Q,表示测试数据的组数。

每组测试数据的第一行为一个正整数N,表示小卖部中零食的数量。

接下来的N行,每行为一个正实数A和一个正整数B,表示这种零食的价格和小Ho对其的渴望度。

一种零食仅有一包。

对于100%的数据,满足1 <= Q <= 10,1<=N<=50,0<A<=10,1<=B<=100

对于100%的数据,满足A的小数部分仅可能为0.5或0。

输出

对于每组测试数据,输出一个整数Ans,表示小Ho可以获得最大的渴望度之和。

样例输入

1
4
0.5 6
4.5 7
5.0 4
2.0 9

样例输出

17

分析

一开始以为是背包问题,但是约束条件并不像背包问题那样...索性暴力枚举了。类似于two / three sum。

时间:O(N^3)

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>

using namespace std;

int Q, N;

bool meet(double x)
{
    return (x == (int)x && (int)x % 5 == 0);
}

int main()
{
    cin >> Q;
    for (int t = 0; t < Q; ++t) {
        cin >> N;

        double a;
        int b;
        vector<pair<int, double> > snacks;

        for (int i = 0; i < N; ++i) {
            scanf("%lf%d", &a, &b);
            snacks.push_back(make_pair(b, a));
        }

        int n = snacks.size(), ret = 0;
        double x;

        for (int i = 0; i < n; ++i) {
            x = snacks[i].second;
            if (meet(x)) {
                ret = max(ret, snacks[i].first);
            }
        }

        for (int i = 0; i < n - 1; ++i) {
            for (int j = i + 1; j < n; ++j) {
                x = snacks[i].second + snacks[j].second;
                if (meet(x)) {
                    ret = max(ret, snacks[i].first + snacks[j].first);
                }
            }
        }

        for (int i = 0; i < n - 2; ++i) {
            for (int j = i + 1; j < n - 1; ++j) {
                for (int k = j + 1; k < n; ++k) {
                    x = snacks[i].second + snacks[j].second + snacks[k].second;
                    if (meet(x)) {
                        ret = max(ret, snacks[i].first + snacks[j].first + snacks[k].first);
                    }
                }
            }
        }

        cout << ret << endl;
    }

    return 0;
}

原文地址:https://www.cnblogs.com/ilovezyg/p/6486240.html