题意:
给你n个商品,每个商品都有两个参数 p d ,p为该商品卖出后的利润,d表明该商品只能在这个期限之前卖出,一天只能卖出一件商品。
问你这批商品最多能获得多少利润
题解:
贪心!!!
按照利润从大到小排序,如果利润相同就按照期限从大到小排序,这样才能保证在一定期限内卖更多的商品获得更大的利润
排序完成后,枚举每个商品的结束的时间,然后向前暴力(找到离这个期限最近的且可占用的时间),如果当前时间可以卖出即没被vis数组标记,就可以再在当前时间卖出
代码:
#include<iostream> #include<stdio.h> #include<math.h> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2e5+5; int vis[maxn]; int n; struct node { int p,d; bool operator < (const node &a)const { if(p==a.p)return d>a.d; return p>a.p; } }a[maxn]; int main() { while(~scanf("%d",&n)) { memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].d); } sort(a+1,a+n+1); int ans=0; for(int i=1;i<=n;i++) { int tmp=a[i].d; for(int j=tmp;j>=1;j--) { if(!vis[j]) { vis[j]=1; ans+=a[i].p; break; } } } printf("%d\n",ans); } return 0; }
对于贪心的情况,可以用并查集进行优化 找到离这个期限最近的且可占用的时间
f【】数组存放当前期限,找到一个商品 f【x】=x ,那么当前时间可以使用,然后让f【x】=x-1,表示x期限被标记,然后将他的期限x-1(这个时间用过之后,离x时间期限最近的时间就是x-1)如果 f【x】= 0 则表示没有位置了,就不再记录了
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2e5+5; int f[maxn]; int n; struct node { int p,d; bool operator < (const node &a)const { if(p==a.p)return d>a.d; return p>a.p; } }a[maxn]; int Find(int x) { return f[x]==x?x:f[x]=Find(f[x]); } int main() { while(~scanf("%d",&n)) { for(int i=0;i<maxn;i++)f[i]=i; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].d); } sort(a+1,a+n+1); int ans=0; for(int i=1;i<=n;i++) { int tmp=Find(a[i].d); if(tmp>0) { f[tmp]=tmp-1; ans+=a[i].p; } } printf("%d\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/j666/p/11613802.html
时间: 2024-10-26 20:45:20