P7302 [NOI1998] 免費的餡餅
阿新 • • 發佈:2022-03-05
題面
SERKOI 最新推出了一種叫做 “免費餡餅” 的遊戲:遊戲在一個舞臺上進行。舞臺的寬度為 \(w\) 格(從左到右依次用 \(1\sim w\) 編號),遊戲者佔一格。開始時遊戲者可以站在舞臺的任意位置,手裡拿著一個托盤。下圖為天幕的高度為 \(4\) 格時某一個時刻遊戲者接餡餅的情景。
遊戲開始後,從舞臺天幕頂端的格子中不斷出現餡餅並垂直下落。遊戲者左右移動去接餡餅。遊戲者每秒可以向左或者向右移動一格或兩格,也可以以站在原地不動。
當餡餅在某一時刻恰好到達遊戲者所在的格子中,遊戲者就收集到了這塊餡餅。當餡餅落在一個遊戲者不在的格子裡時該餡餅就消失。
寫一個程式,幫助我們的遊戲者收集餡餅,使得所收集餡餅的分數之和最大。
思路
免費的餡餅,免費的陷阱。
1.貪心做法
先對原資料排序(優先時間從小到大,然後是價值從大到小)。然後跑貪心。先選第一個,然後如果時間足夠移動就移動。
複雜度是 \(O(n\log n)\)。
#include <bits/stdc++.h> using namespace std; struct Pie{ int t,p,v; } a[100005],last; int w,n,ans; bool cmp(Pie x,Pie y){ if(x.t==y.t){ return x.v>y.v; } else{ return x.t<y.t; } } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>w>>n; for(int i=1;i<=n;i++){ cin>>a[i].t>>a[i].p>>a[i].v; } sort(a+1,a+n+1,cmp); last=a[1]; ans=a[1].v; for(int i=2;i<=n;i++){ if(2*(a[i].t-last.t)>=abs(a[i].p-last.p)){ ans+=a[i].v; last=a[i]; } } cout<<ans<<endl; return 0; }
可以水 \(50\) 分。