HDU 6709“Fishing Master”(贪心+优先级队列)
傳送門
?參考資料
2019CCPC網絡選拔賽 H.Fishing Master(思維+貪心)
?題意
池塘里有 n 條魚,捕捉一條魚需要花費固定的 k 時間;
你有一個鍋,每次只能煮一條魚,其中煮熟第 i 條魚至少需要 ti?時間;
你在煮魚的時候可以選擇去釣一條魚,也可也選擇不釣;
但是,一旦你決定釣魚,就必須花費 k 時間調到一條魚;
任何時刻,你都可以有多條魚待煮;
問將所有的魚釣上來并煮熟所有的魚最少需要多少時間;
?題解
理想的方案是只有在釣第一條魚的時候鍋是空的,其余任意時刻,鍋都在做有用功;
鍋在做有用功指的是第 i 條魚在鍋中煮的前 ti?時間,多煮的時間稱鍋在做無用功;
這種情況下,只需要且必須花費?$k+\sum_{i=1}^{n}t_i$ 時間就可以將所有魚全部釣上來并全部煮好;
那么,實際情況并非如此,要想花費最少的時間,首先得明確在什么情況下可能會導致時間浪費;
假設你當前煮的魚需要花費 t 時間,釣魚需要花費 k 時間;
你可以在這 t 時間內釣 $\frac{t}{k}$?條魚上來,在釣魚的時間,鍋處于煮魚狀態;
但是剩下的 t%k 時間不足以再釣一條上來;
此時,你就有兩個決策可以選擇:
決策1:去釣下一條魚;
決策2:等待 t%k 時間往鍋中放入下一條魚;
當然,選擇 決策2 的前題是你得有魚可煮;
如果你手中有魚的話,肯定要選擇 決策2,因為等待的這 t%k 時間是必須的;
而如果選擇 決策1,那么煮當前這條魚會花費 t+k-t%k 時間,前 t 時間鍋在做有用功,是必須的;
但是后 k-t%k 時間,鍋就在做無用功,是在浪費時間;
如果你當前手中無魚,那么你不得不去釣魚,那么就一定要浪費當前的 k-t%k 時間么?
假設你現在已經煮了 i 條魚(包括當前煮的這條魚);
那么,你完全可以在前 i 條魚中找個 tj%k($j \in [1,i]$)大的從而使得浪費的 k-tj%k 時間盡可能的小;?
找 tj%k 大的就可以使用優先級隊列了;
那么,接下來就要分析一下優先釣哪條魚了;
當然是優先釣煮的時間較長的魚了,因為在煮這條魚的時候,你會盡可能多的釣上來其他的魚,從盡可能多的選擇決策2;
?代碼
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1e5+50; 5 ll t[maxn]; 6 int n; 7 ll k; 8 9 int main() 10 { 11 ios::sync_with_stdio(0); 12 int T; 13 cin>>T; 14 while(T--) 15 { 16 cin>>n>>k; 17 for(int i=1;i<=n;i++) 18 cin>>t[i]; 19 sort(t+1,t+1+n,greater<int>());///為了保證盡可能多釣魚 20 ll ans=k;///釣第一條魚時間 21 ll cnt=1;///可煮的魚數 22 priority_queue<int> pq; 23 for(int i=1;i<=n;i++)///煮魚 24 { 25 ans+=t[i]; 26 cnt+=t[i]/k;///煮魚時所釣的魚 27 28 ///已經沒有可煮的魚,需要釣魚 29 ///由于t是從大到小排序, 30 ///當前煮魚時已釣不到魚,那以后也釣不到 31 ///需要額外長時間煮魚以去釣魚 32 if(cnt<i) 33 { 34 ans+=k-pq.top(); 35 pq.pop(); 36 } 37 pq.push(t[i]%k);///k-t[i]%k小 額外功少 38 } 39 cout<<ans<<"\n"; 40 } 41 } View Code?
轉載于:https://www.cnblogs.com/MMMinoz/p/11431748.html
總結
以上是生活随笔為你收集整理的HDU 6709“Fishing Master”(贪心+优先级队列)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [PHP] 项目实践中的自动加载实现
- 下一篇: 主席树之初见