ZOJ3385 - Hanami Party (贪心)
題目鏈接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3385
題目大意:
妖夢(mèng)要準(zhǔn)備一個(gè)party,所以需要許多食物,初始化妖夢(mèng)的烹飪技能為L,每天妖夢(mèng)有兩種選擇,一是選擇當(dāng)天做L個(gè)食物,二是提升自己的烹飪技能為L+1。
但是幽幽子非常能吃,每天幽幽子都要吃Ai的食物,當(dāng)沒(méi)食物吃后幽幽子會(huì)非常生氣,甚至想把妖夢(mèng)批判一番。所以現(xiàn)在妖夢(mèng)要保證做出的食物每天夠幽幽子吃的情況下盡量的多。
解題過(guò)程:
好久好久之前比賽的題,一直沒(méi)補(bǔ),當(dāng)初知道是貪心和棧,感覺(jué)這樣的思維題加簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)的題非常難……也可能是直接接觸的題太少吧。
題目分析:
首先用棧去貪心的模擬,在能保證夠幽幽子吃的情況下,最多能夠?qū)⒓寄芴岣叩綆准?jí)。
假設(shè)每天都提高等級(jí)并且將天數(shù)入棧,當(dāng)當(dāng)前剩下的食物不夠幽幽子吃的話(huà),將上一次提升等級(jí)的地方換成做食物。如果還是不夠幽幽子吃的話(huà),那么就是無(wú)解的。
因?yàn)樘岣叩燃?jí)是一個(gè)持久性的加成,當(dāng)然是越早提升越好,所以每次將提高等級(jí)換做做食物的地方都是最晚的地方。
這樣求解出最高可以升到幾級(jí)后,再去求下最大能達(dá)到多少食物。
同樣效仿上面的操作,每次取出最近的提升等級(jí)的地方換成做食物,去維護(hù)一個(gè)最大值。
不過(guò)有可能有這樣的一個(gè)情況,在租個(gè)替換掉提升等級(jí)時(shí),可能某個(gè)地方替換掉提升等級(jí)后食物就不夠幽幽子吃了。但是這種情況,求出的結(jié)果肯定比維護(hù)的最大值要小,因?yàn)楝F(xiàn)在食物不夠吃了,并且等級(jí)還低了,那么最后算出的剩余一定是更小的。
AC代碼:
#include <stdio.h> #include <stack> using namespace std;typedef long long LL;int main() {LL N, L;while (~scanf("%lld %lld", &N, &L)) {LL sum = 0;bool flag = true;stack<LL> ss;for (int i = 1; i <= N; i++) {LL eat;//每天要吃的食物數(shù)scanf("%lld", &eat);if (!flag)continue;ss.push(i);L++;//如果當(dāng)前剩余的食物不夠的話(huà),去替換掉之前提升等級(jí)while (sum < eat && !ss.empty()) {LL t = ss.top();L--;ss.pop();//將提升等級(jí)替換成做食物是很容易維護(hù)的,首先讓等級(jí)減一,加上等級(jí),然后當(dāng)從提升等級(jí)那天到至今的提升等級(jí)的加成減去sum += L - (i-t);}if (sum < eat) {flag = false;continue;}sum -= eat;}if (!flag) {printf("Myon\n");continue;}LL ans = sum;//求出最大值,類(lèi)似上面的過(guò)程while (!ss.empty()) {LL t = ss.top();L--;ss.pop();sum += L - (N - t);ans = max(ans, sum);}printf("%lld\n", ans);} }轉(zhuǎn)載于:https://www.cnblogs.com/ACMFish/p/7222821.html
總結(jié)
以上是生活随笔為你收集整理的ZOJ3385 - Hanami Party (贪心)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SQL转化为MapReduce的过程
- 下一篇: Nagios学习实践系列