uva-10026-贪心

题意:有N项工作,每项工作完成需要n天,如果不开始做每天罚fee,开始做即不罚钱,求任务的执行顺序,使得罚钱最少.如果有多组答案,取下标排列最小的那组

解题思路:

考虑工作tn(dn,fn) ,

假如先做工作tj,  0<j<n,0<i<n,那么罚的钱是 dj*f0+dj*f1+.....dj*fn+dj*fi = totalj1,

在做工作ti,  di*f0+di*f1+....di*fn = totalj2,   totalj1 + totalj2 = (di+dj)*fo + (di+dj)*f1 +....(di+dj)fn + (dj*fi)

假如先做工作ti,0<i<n,那么罚的钱是 di*f0+di*f1+....di*fn+di*fj = totali1,

再做tj,dj*f0+dj*f1+.....dj*fn=totali2,   totali1+totali2 = (di+dj)*fo + (di+dj)*f1 +....(di+dj)fn +(di*fj)

差别就是di*fj和dj*fi

#include <algorithm>
#include <iostream>

namespace cc
{
using std::cin;
using std::cout;
using std::endl;
using std::move;
using std::qsort;
const int N = 1000;
class Node
{
  public:
    int fee;
    int day;
    int index;
    Node(int fee, int day, int index) : day(day), fee(fee), index(index)
    {
    }
    Node() = default;
};

int cmp(const void *a, const void *b)
{
    Node *n1 = (Node *)(a);
    Node *n2 = (Node *)(b);
    int total1 = n1->fee * n2->day;
    int total2 = n2->fee * n1->day;
    if (total1 == total2)
    {
        return n1->index - n2->index;
    }
    if (total1 < total2)
        return 1;
    return -1;
}

void solve()
{
    int n;
    cin >> n;
    int t = 0;
    while (n--)
    {
        if(t!=0)
        cout<<endl;
        ++t;
        int k;
        cin >> k;
        int fee, day;
        int total = 0;
        Node nodes[N];
        for (int i = 0; i < k; i++)
        {
            cin >> day >> fee;
            Node node(fee, day, i + 1);
            nodes[total++] = node;
        }
        qsort(nodes, total, sizeof(Node), cmp);

        cout << nodes[0].index;
        for (int i = 1; i < total; i++)
            cout << " " << nodes[i].index;
        cout << endl;
    }
}

} // namespace cc

int main()
{
#ifndef ONLINE_JUDGE
    freopen("/Users/caicai/in", "r", stdin);
#endif // !ONLINE_JUDGE

    cc::solve();
    return 0;
}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/10009361.html