uva-10026-贪心

时间:2023-03-08 17:56:23

题意:有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 = ;
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 ;
return -;
} void solve()
{
int n;
cin >> n;
int t = ;
while (n--)
{
if(t!=)
cout<<endl;
++t;
int k;
cin >> k;
int fee, day;
int total = ;
Node nodes[N];
for (int i = ; i < k; i++)
{
cin >> day >> fee;
Node node(fee, day, i + );
nodes[total++] = node;
}
qsort(nodes, total, sizeof(Node), cmp); cout << nodes[].index;
for (int i = ; 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 ;
}