首页 > 其他分享 >Supermarket 3种解法保证看懂

Supermarket 3种解法保证看懂

时间:2023-06-06 18:55:23浏览次数:41  
标签:商品 int sum Supermarket vis 保证 long 解法 cmp

Description

给定N个商品

每个商品有利润 p_i 和过期时间 d_i

每天只能卖一个商品,过期商品不能再卖,

求如何安排每天卖的商品,可以使收益最大。

1≤N,p_i,d_i≤10^4。

Format

Input

测试做到文件底结束

对于每组数据,先给出数字N

接下来N行,每行两个数字代表pi与di

Output

如题

Samples

输入数据 1

4  
50 2  
10 1   
20 2   
30 1
7  
20 1   
2 1   
10 3  
100 2   
8 2
5 20  
50 10

输出数据 1

80
185

 题目大意:有n个商品,每个商品都有一个值,第一个是其价值,第二个是其过期日期,每一天只能卖一件商品,问最大利润。

sol1:拿到这个题目第一眼想到的就是贪心,可以先卖贵的,然后每一件商品尽可能晚的卖出

所以可以先按利润排序然后,枚举每个商品用一个vis数组来标记每一个时间点是否被占用,如果找到一个时间点标记为被占用,累加答案;贴出代码

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct A{
	int x,y;
}a[10050];
int n,ans,t;
bool cmp(A q,A w){
	return q.y>w.y;
}
bool vis[10050];
signed main(){
	while(cin>>n){
		ans=0;
		for(int i=1;i<=n;i++)
			cin>>a[i].y>>a[i].x;
		memset(vis,0,sizeof(vis));
		sort(a+1,a+n+1,cmp);//按利润排序 
		for(int i=1;i<=n;i++)
			for(int j=a[i].x;j>=1;j--){//找一个最晚的空余时间点 
				if(vis[j]==0){//如果找到一个空余时间点 
					vis[j]=1;//标记为被占用 
					ans+=a[i].y;
					break;
				}
			}
		cout<<ans<<'\n';
	}
	return 0;
}

时间复杂度O(n^2),可以通过此题;

sol2:考虑优化, 找一个最晚的空余时间点的时候用了一个for循环枚举太过浪费,可以用并查集优化,可以建立一个关于天数的并查集,对于每个商品,若它在d天只有过期,就在并查集中查询d的根R,若R大于0,则安排在第R天卖出,然后把R和R-1合并(还是不懂可以手动在纸上画一下),代码:

#include<bits/stdc++.h>
#define in long long
using namespace std;
int f[10010],n,r,sum;
struct A{
	int t,w;
}a[10010];
bool cmp(A q,A w){
	return q.w>w.w;
}
int find(int x){
	if(f[x]!=x) f[x]=find(f[x]);
	return f[x];
}
signed main(){
	while(cin>>n){
		sum=0;
		for(int i=1;i<=1e4;i++)
			f[i]=i;
		for(int i=1;i<=n;i++)
			cin>>a[i].w>>a[i].t;
		sort(a+1,a+n+1,cmp);//按利润排序 
		for(int i=1;i<=n;i++){
			r=find(a[i].t);//寻找d的根 
			if(r>0){//如果r>0 
				f[r]=r-1;//将r和r-1合并 
				sum+=a[i].w;
			}
		}
		cout<<sum<<"\n";
	}
	return 0;
}

时间复杂度O(nlogn) ,相对于第一种,优化了不少;

sol3:还可以考虑,另一种贪心,用堆来优化先按时间排个序,然后依次放入堆中,如果还有可用时间 ,直接压入堆中,否则每次用利润大的替换小的;代码:

#include<bits/stdc++.h>
#define in long long
using namespace std;
int n,r,sum,now;
struct A{
	int t,w;
}a[10010];
bool cmp(A q,A w){
	return q.t<w.t;
}
priority_queue<int, vector<int>, greater<int> > q;//建立一个小根堆 
signed main(){
	while(cin>>n){
		sum=0;now=0;
		for(int i=1;i<=n;i++)
			cin>>a[i].w>>a[i].t;
		sort(a+1,a+n+1,cmp);//按时间排序 
		for(int i=1;i<=n;i++){
			if(now<a[i].t){//如果还有可用时间 
				now++;//已占用时间+1 
				q.push(a[i].w);//压入堆中 
			}else if(q.size()>0&&a[i].w>q.top()){//如果利润大于堆顶 
				q.pop();
				q.push(a[i].w);//用大的替换小的 
			}
		}
		while(!q.empty()){
			sum+=q.top();
			q.pop();
		}
		cout<<sum<<"\n";
	}
}

时间复杂度O(nlogn) ,和并查集做法差不多

标签:商品,int,sum,Supermarket,vis,保证,long,解法,cmp
From: https://www.cnblogs.com/2011tnm/p/17461449.html

相关文章

  • 应用问题解决-分布式锁(LUA保证删除原子性)
    问题:删除操作缺乏原子性场景1、index1获得锁、执行具体操作、比较lock的uuid值确实和自己生成的uuid是否相等,相等则删除锁。uuid=v1set(lock,uuid)uuid.equals(get("lock"))2、但是index1执行删除前,lock刚好过期时间已经到了,被redis自动释放3、此时index2获取锁,执行具体......
  • 【IDE】Chrome 在其他机器登陆 Google 账号,没有退出,怎么及时保证账号及数据安全?
    Chrome浏览器,再配合Google账号,确实给我们带来了很多方便比如:书签同步,扩展插件同步,数据同步但是,当我们在别人的机器上登录Google账号后,如何及时保障账号安全呢?有人说,这有什么担心的?是,正常来说我们不需要操这份心。就怕碰到极端的人,或者别人的误操作,导致我们Google账号的......
  • 微分方程的解法
     ......
  • 关闭浏览器后再次访问session 保证是同一个sessionid
    我们知道在正常情况下,发送http请求时,消息头中会自动携带cookie信息,这其中就会包括SESSIONID信息,所以只要我们没有关闭浏览器,消息头中都会自动携带这个信息,以供服务器访问相应的session。 但是如果我把浏览器关闭了呢?这样的话,我该如何再次访问相应的session呢?我们可以这样做,来实现......
  • volatile为什么不能保证原子性
    首先要了解的是,volatile可以保证可见性和顺序性,这些都很好理解,那么它为什么不能保证原子性呢?可见性可见性与Java的内存模型有关,模型采用缓存与主存的方式对变量进行操作,也就是说,每个线程都有自己的缓存空间,对变量的操作都是在缓存中进行的,之后再将修改后的值返回到主存中,这就带......
  • 系数矩阵为Hessian矩阵时的使用Pearlmutter trick的共轭梯度解法
    共轭梯度法已经在前文中给出介绍:python版本的“共轭梯度法”算法代码  =======================================  使用共轭梯度法时,如果系数矩阵为Hessian矩阵,那么我们可以使用Pearlmuttertrick技术来减少计算过程中的内存消耗,加速计算。 使用Pearlmuttertrick的......
  • dfs 二叉树中序遍历迭代解法——求解BST中第k小元素
    BST中第K小的元素中文English给一棵二叉搜索树,写一个 KthSmallest 函数来找到其中第K小的元素。Example样例1:输入:{1,#,2},2输出:2解释: 1 \ 2第二小的元素是2。样例2:输入:{2,1,3},1输出:1解释:2/\13第一小的元素是1。Challenge如果这棵BST经常会被修改(......
  • 请访问我的个人blog,这边的随笔不保证更新维护
    在此,和大家说声抱歉。我在博客园这边发过的随笔,不保证更新维护。当然,我会保留个人认为还算有点参考价值的博文。如果你觉得我的博文能给你带来帮助,可以看我的个人博客:https://blog.cnwangk.top/......
  • 新建T1,T2,T3线程,如何保证它们执行的顺序性
    在多线程中有多种方法让线程按特定顺序执行,可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。  ......
  • 【Azure 媒体服务】Azure Media Service上传的视频资产,如何保证在Transfer编码后音频
    问题描述AzureMediaService上传的视频资产,如何保证在Transfer编码后音频文件和视频文件不分成两个文件?保持在一个可以直接播放的MP4文件中呢? 问题解答AzureMediaService上提供的Build-inTransform生成的资产中,音频与视频分别存储在不同的文件中。通过自定义StandardEncode......