清明講過一道類似的,難度略大的:P3545 [POI2012]HUR-Warehouse Store
兩道題類似,都是暫時先把前面的加進候選集合里,如果超出限制的話就拿現在這個和前面的交換,
相當於不選前面那個選當前這個,應該是比較好的思想
這道題還有一個就是如果最優解要你走到那個點,那麼中間的路程是不可省略的,所以貪心時大可不考慮
反正實質上是個dp,取的是最大值
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=100010; ll n,m,cnt,sum,ans,tmp; struct node{ ll x,t; }a[maxn]; bool cmp(node a,node b){return a.x<b.x;} int main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++){ ll x,t;scanf("%lld%lld",&x,&t); if(x<=m && t<=m) a[++cnt].x=x,a[cnt].t=t; } sort(a+1,a+1+cnt,cmp); priority_queue<ll>q; for(int i=1;i<=cnt;i++){ sum+=a[i].t+a[i].x-a[i-1].x;//先選上這次的 q.push(a[i].t); tmp++; while(sum>m){//要超過時限就替換最大的 sum-=q.top();q.pop(); tmp--; } ans=max(ans,tmp);//根本上是个dp,取f[1]~f[n]最大值 } printf("%lld",ans); }
另一題的代碼
//by jackpei #include<iostream> #include<cstdio> #include<algorithm> #include<queue> #define ll long long using namespace std; const int maxn=250010; struct node{ int val,t; node(int vv,int tt){ val=vv,t=tt; } bool operator <(const node &b)const{ return val<b.val; } }; priority_queue<node>pq; int n,a[maxn],b[maxn],vis[maxn]; ll res; int ans; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++){ res+=(a[i]-b[i]),vis[i]=1,++ans; pq.push(node(b[i],i)); while(res<0) res+=pq.top().val,vis[pq.top().t]=0,pq.pop(),ans--; } printf("%d\n",ans); for(int i=1;i<=n;i++) if(vis[i])printf("%d ",i); }
原文地址:https://www.cnblogs.com/superminivan/p/10764060.html
时间: 2024-10-10 20:19:13