H - Fishing Master (炖鱼)(贪心+思维)

传送门

题目大意:

        T组输入, 每组输入第一行 n,  k 分别是鱼的个数,和钓鱼的所用时间。 下面一行n个数代表炖好第 i 条鱼所用时间。

        可以在炖鱼的时候去钓鱼,也可以在钓鱼的时候去炖鱼,但是不能在钓鱼的过程中回去重新炖其他鱼。求最短完成时间。

思路:

        烹饪一条鱼结束前,能把鱼钓上来,是最理想的情况。因此先求出能在每次烹饪过程结束前钓出来几条鱼:cnt += ti / k(i = 1~n),cnt = min(cnt, n)。不能在每条鱼烹饪结束前钓上来的鱼数量就是 n - cnt - 1(第一条鱼必须先钓,不能在烹饪过程中进行,所以先减去)。

        将每个烹饪时间对钓鱼时间取余,从大到小排序。我们将不能在烹饪结束前就钓上来的鱼,分别安排在这些烹饪时间余数最大的地方,这样重叠时间越多,多出来的时间就会越少。

        总时间 = 烹饪总时间 + 钓鱼多出来的时间(烹饪完了,鱼没钓完,多出来的时间)。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
#define int long long
typedef pair<int, int> PII;
const int Max = 0x3f3f3f3f3f3f3f3f;
const int Min = -0x3f3f3f3f3f3f3f3f;
int n, m, k;
int T;
int ans, cnt, a[N];
bool cmp(int aa, int bb)
{
    return aa > bb;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> T;
    while (T--)
    {
        ans = 0, cnt = 0;  //初始化
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            ans += a[i];       //炖鱼的总时间
            cnt += a[i] / m;   //炖鱼的时候可以钓上来几条鱼
            a[i] %= m;      //炖完整的鱼之后剩下的时间余数
        }
        cnt = min(cnt, n);  //与总鱼数取小(因为可以炖鱼的数量可能大于总数)
        sort(a + 1, a + n + 1, cmp);   //将余数从大到小排序
        for (int i = 1; i <= n - cnt - 1; i++)  //第一条鱼钓上来之前不能炖鱼,要除去第一条鱼,所以是n-cnt-1,
        {
            ans += m - a[i];    //加上在炖完鱼,但是鱼还没钓完,重叠后多用的时间
        }
        cout << ans + m << "\n"; //所用时间再加上第一条鱼钓上来的时间
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值