1. 程式人生 > 其它 >ADV-1181 搬運冰塊(貪心)

ADV-1181 搬運冰塊(貪心)

問題描述

  醜楓接到了一份奇葩的工作:往冰庫裡搬運冰塊.冰庫外放著N箱冰塊,由於室外溫度高,冰塊會很快融化,且每箱冰塊的融化速度不同.因為每箱冰塊的體積,質量不等,把每箱冰塊搬運進冰塊花費的時間也不同.因此需要合理安排搬運順序,才能使總的冰塊融化量最小.醜楓請你幫忙計算最少的總融化量是多少,以便彙報上司.

輸入格式

  第一行輸入整數N
  接下來N行,每行兩個整數,分別表示每箱冰塊的搬運耗時Ti及融化速度Di.

輸出格式

  輸出最少的總融化量

思路

結論:應該按照di*ti+1 > di+1*ti的順序排列冰塊,融化的量才最小
證明:設第i個冰塊搬運耗時ti,融化速度di, 第i+1個冰塊搬運耗時ti+1,融化速度di+1
那麼,將這兩個冰塊交換搬運順序,考慮交換後融化的量為多少。
顯然,交換這兩個冰塊不會影響其他冰塊的融化量

#include <iostream>
#include <cstring>
#include <algorithm>

#define x first
#define y second

using namespace std;

const int N = 1000010;
typedef long long LL;
typedef pair<int, int> PII;

PII ice[N];

bool cmp(PII a, PII b)
{
    return a.y*b.x > b.y*a.x;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++ )
    {
        int t, d;
        scanf("%d%d", &t, &d);
        ice[i] = {t, d};
    }
    sort(ice + 1, ice + 1 + n, cmp);
    LL sum = 0;
    int t = 0;
    for(int i = 1; i <= n; i ++ )
    {
        sum += ice[i].y * t;
        t += ice[i].x;
    }
    cout << sum;
    return 0;
}