Fishing Master (思维+贪心)

题目网站:
http://acm.hdu.edu.cn/showproblem.php?pid=6709

Problem Description

Heard that eom is a fishing MASTER, you want to acknowledge him as your mentor. As everybody knows, if you want to be a MASTER’s apprentice, you should pass the trial. So when you find fishing MASTER eom, the trial is as follow:
There are n fish in the pool. For the i - th fish, it takes at least ti minutes to stew(overcook is acceptable). To simplify this problem, the time spent catching a fish is k minutes. You can catch fish one at a time and because there is only one pot, only one fish can be stewed in the pot at a time. While you are catching a fish, you can not put a raw fish you have caught into the pot, that means if you begin to catch a fish, you can’t stop until after k minutes; when you are not catching fish, you can take a cooked fish (stewed for no less than ti) out of the pot or put a raw fish into the pot, these two operations take no time. Note that if the fish stewed in the pot is not stewed for enough time, you cannot take it out, but you can go to catch another fish or just wait for a while doing nothing until it is sufficiently stewed.
Now eom wants you to catch and stew all the fish as soon as possible (you definitely know that a fish can be eaten only after sufficiently stewed), so that he can have a satisfying meal. If you can complete that in the shortest possible time, eom will accept you as his apprentice and say “I am done! I am full!”. If you can’t, eom will not accept you and say “You are done! You are fool!”.
So what’s the shortest time to pass the trial if you arrange the time optimally?

Input

The first line of input consists of a single integer
T(1≤T≤20), denoting the number of test cases.
For each test case, the first line contains two integers n(1≤n≤1e5),k(1≤k≤1e9)
, denoting the number of fish in the pool and the time needed to catch a fish.
the second line contains n integers, t1 , t2 , … ,tn (1≤ti≤109),denoting the least time needed to cook the i-th fish.

Output

For each test case, print a single integer in one line, denoting the shortest time to pass the trial.
Sample Input
2
3 5
5 5 8
2 4
3 3
Sample Output
23
11

Hint

Case 1: Catch the 3rd fish (5 mins), put the 3rd fish in, catch the 1st fish (5 mins), wait (3 mins),
take the 3rd fish out, put the 1st fish in, catch the 2nd fish(5 mins),
take the 1st fish out, put the 2nd fish in, wait (5 mins), take the 2nd fish out.
Case 2: Catch the 1st fish (4 mins), put the 1st fish in, catch the 2nd fish (4 mins),
take the 1st fish out, put the 2nd fish in, wait (3 mins), take the 2nd fish out.

题目大意就是有n条鱼要捉来煮,每次捉鱼都需要k分钟,但每条鱼要煮t分钟,求出最快煮完所有鱼的时间。
这道题一开始直接让我跟队友自闭,一开始的思路是把煮时间长的鱼先钓上来,而且!一开始找出的样例都证明可行并且敲了出来,然后wa(-5)。后来出了个反例推翻了。在最后8分钟想出了ac思路,就是把每条鱼要煮的时间,如果大于k,就再煮的时候捉t[i]/k条鱼,剩下的时间再就到数组。这样我们就可以得出一个时间全小于k的数组(如果鱼还没有钓完,而如果鱼已经掉完,接下来安心煮鱼就好)。此时无论有多少条鱼没钓没煮,都必须在每条鱼煮的时候钓一条鱼,直到所有鱼钓完。所以此时把得到的数组从大到小排序,有多少条鱼没钓,sum就加多少个k,再加上剩下的鱼要煮的时间,即可得出答案。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sum ;
int num , t , n , k , a[100005] ;
int cmp(int a,int b){return a>b;}
int main () {
 ios::sync_with_stdio(false);
 cin >> t ;
 while (t--){
  cin >> n >> k ;
  num = 1 ;  //先捉一条鱼上来煮
  sum = k ;  //第一条鱼的时间
  for (int i = 1 ; i <= n ;  i++){
   cin>>a[i];
   if (num < n){
    int x = a[i] / k ; //当前煮鱼时间最多可以完整得捉多少鱼
    if (num + x >= n){
     a[i] = a[i] - (n - num) * k ;
     sum = sum + (n - num) * k ;
     num = n ;
    }else{
     sum = sum + x * k ;
     a[i] = a[i] % k ;
     num = num + x ;
    }
   }
  }
  sort(a+1,a+1+n,cmp);  //此时数组里的数都是小于K的,所以先算捉鱼时间,捉完鱼但没煮的就安心煮鱼好了
  for(int i = 1 ; i <= n ; i++){
   if(num<n){
    sum = sum + k ;
    num++;
   }else{
    sum = sum + a[i];
   }
  }
  cout<<sum<<endl;
 }
 return 0;
}

原文地址:https://www.cnblogs.com/jjmmboom/p/11470233.html

时间: 2024-11-01 23:40:16

Fishing Master (思维+贪心)的相关文章

Fishing Master HDU - 6709 (贪心)acm

Heard that eomeom is a fishing MASTER, you want to acknowledge him as your mentor. As everybody knows, if you want to be a MASTER's apprentice, you should pass the trial. So when you find fishing MASTER eomeom, the trial is as follow: There are nn fi

【Fishing Master HDU - 6709 】【贪心】

题意分析 题意:题目给出n条鱼,以及捕一条鱼所用的时间k,并给出煮每一条鱼的时间,问抓完并煮完所有鱼的最短时间. 附题目链接 思路: 1.捕第一条鱼的时间是不可避免的,煮每条鱼的时间也是不可避免的,这些都要算上. 2.可以优化的是煮鱼的时间,在时间允许的范围内可进行捕其他鱼.当然煮鱼的时间也许不够捕其他鱼,这就需要增加额外的时间. 3.设在煮每条鱼煮的时间内抓的最多的鱼数为cnt,捕鱼的时间为cost,将每次额外增加的时间存储在一个数组中,记为fre[ ]. 4.更多详细信息在代码中给出. AC

Straight Master (贪心)

题目如下:A straight is a poker hand containing five cards of sequential rank, not necessarily to be the same suit. For example, a hand containing 7 club, 6 spade, 5 spade, 4 heart and 3 diamond forms a straight. In this problem, we extend the definition

HDU 4343 多查询求区间内的最大不相交区间个数-思维&amp;贪心-卡时间&amp;二分&amp;剪枝

题意:给你一些区间,现在有m个查询,求出每个查询的区间内的最大的不相交区间个数 分析: 几天前那道说谎问题时用dp的摞箱子模型求的最大的不相交区间个数,但是这题不能用这个方法,因为这题是动态的查询,不可能每个查询dp一次,超时. 这题用贪心策略.求区间[l~r]里的最大不相交区间,贪心策略就应该先选该区间内右端点最小的,这样给以后待选的区间留下更大的空间,所以我们的做法就是先按照区间的右端点排序,然后每次查询依次挑出查询区间里右端点最小的,并且把查询区间的左端点更新为刚才挑出的区间的右端点(这个

NYOJ 30 &amp;&amp; POJ 1042 Gone Fishing(枚举+贪心)

[题目链接]:Click here~~ [题目大意]: 一个人去钓鱼,在一条单向路上的旁边有n个湖,并且从湖i到湖i+1需要ti的时间,每个湖里面有fi条鱼,每钓一次鱼,鱼会减少di条.在给定时间T内,问如何才能使钓的鱼最多,并记录在各个湖上停留的时间. [解题思路] 此题细节处理好多麻烦,一定要认真看清题意,POJ WA了无数遍,纠结一天.参考了别人的题解,思路如下: 首先须注意的一点是,John只能向前走,返回的话只会增加John在路上的时间,因而减少他钓鱼的时间.因此此题解题步骤如下: 1

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra

Codeforces 1093C (思维+贪心)

题面 传送门 题目大意: 有一个长n(n为偶数)的序列a 已知a满足 \(a_1≤a_2≤?≤a_n\) 给出一个长度为\(\frac{n}{2}\) 的序列b,定义\(b_i=a_i+a_{n-i+1}\) 求出序列a (输出任意一种答案即可) 分析 为了保证序列不下降,我们采用贪心的思想,先假设\(a_i=a_{i-1}\),这样给后面的数留有的余地更大 然后计算出\(a_{n-i+1}=b_i-a_i\),如果\(a_{n-i+1}>a_{n-i+1+1}\),即不满足不下降的条件,则进行

CodeForces - 1251E2 (思维+贪心)

题意 https://vjudge.net/problem/CodeForces-1251E2 一共有 n 个选民,你可以付出 pi? 的代价让第 i 个选民为你投票,或者,在为你投票的人数达到 mi? 时,他会主动为你投票而不用你付出任何代价. 问得到所有选民投票的最小代价. 思路 考虑贪心,对容易跟风的就跟风,对不容易跟风的就贿赂,所以对每个mi用vector插入相应的pi,然后从大到小遍历vector(不易跟风的要花钱),对于每一个mi,把对应的p插入到小根堆,小根堆里的人默认是跟风的,设

CodeForces - 1253C(思维+贪心)

题意 https://vjudge.net/problem/CodeForces-1253C n个糖果,一天最多吃m个糖果,每个糖果有个值a[i],第d天会变成d*a[i],问吃k(k=1~n)个糖果权值和的最小值分别是多少. 思路 先排序,再求一遍前缀和. 比如m=2,排序后:2 3 4 4 6 6 7,那么ans[1]=2,ans[2]=5:对于k=3,贪心的想法肯定是把大的两个第一天吃,小的第二天吃,ans[3]=11:对于k,肯定是把最大的m个第一天吃,剩下的可以通过ans[k-m]得到