SCAU 2020寒训 专题1——数据结构

B - 优先队列 POJ - 2970

1.题目描述:
A new web-design studio, called SMART (Simply Masters of ART), employs two people. The first one is a web-designer and an executive director at the same time. The second one is a programmer. The director is so a nimble guy that the studio has already got N contracts for web site development. Each contract has a deadline di.

It is known that the programmer is lazy. Usually he does not work as fast as he could. Therefore, under normal conditions the programmer needs bi of time to perform the contract number i. Fortunately, the guy is very greedy for money. If the director pays him xi dollars extra, he needs only (bi − ai xi) of time to do his job. But this extra payment does not influent other contract. It means that each contract should be paid separately to be done faster. The programmer is so greedy that he can do his job almost instantly if the extra payment is (bi ⁄ ai) dollars for the contract number i.

The director has a difficult problem to solve. He needs to organize programmer’s job and, may be, assign extra payments for some of the contracts so that all contracts are performed in time. Obviously he wishes to minimize the sum of extra payments. Help the director!

Input
The first line of the input contains the number of contracts N (1 ≤ N ≤ 100 000, integer). Each of the next N lines describes one contract and contains integer numbers ai, bi, di (1 ≤ ai, bi ≤ 10 000; 1 ≤ di ≤ 1 000 000 000) separated by spaces.

Output
The output needs to contain a single real number S in the only line of file. S is the minimum sum of money which the director needs to pay extra so that the programmer could perform all contracts in time. The number must have two digits after the decimal point.

Sample Input
2
20 50 100
10 100 50

Sample Output
5.00

2.题意:
大概就是有一个懒惰又贪心的程序员(暗示贪心!)让我们在规定的时间(ddl)内完成所有的项目,并且让我们输出最少花的钱。(又让马儿跑,又让马儿吃最少的草!)

3.思路:
很明显的贪心+优先队列了(毕竟题目就是啊喂!!)。主要是把所有的项目先按ddl排好序,ddl越短就排越前面,然后按照所花的时间累加起来,一旦时间超过了该项目的ddl就从队列中取一个a值最大的出来腾时间(性价比最高啊!),所以队列的排序就按照a值的大小排序,a值越大就排越前面。这会出现两种情况:第一种是,不需要让程序员全部肝完(要命的!),只需要加速一段时间就ok了,然后再放回去;第二种是,全部肝完,(也有可能还不够),再拿一个出来继续加速。

4.代码:

//B - 优先队列
#include<iostream>
#include<stack>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
int n;
struct p
{
	int a,b,d;
	bool operator < (const p&x)const//重载,方便优先队列
	{
		return a<x.a;
	}
}poj[100001];
bool cmp(const p &a,const p &b){return a.d<b.d;}//按照d的时间排序
priority_queue<p> q;
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;++i)
		scanf("%d%d%d",&poj[i].a,&poj[i].b,&poj[i].d);
	sort(poj,poj+n,cmp);
	int sum=0;//所需时间
	double money=0.0;//所花的钱
	for(int i=0;i<n;++i)
	{
		sum+=poj[i].b;
		q.push(poj[i]);//也可以加速这次的项目
		while(sum>poj[i].d)
		{
			p tmp=q.top();q.pop();
			if(tmp.b>(sum-poj[i].d))//如果可加速范围大于所需范围
			{
				tmp.b -= sum-poj[i].d;
				money += (sum-poj[i].d)*1.0/tmp.a;
				sum=poj[i].d;
				q.push(tmp);
			}
			else//不够加速
			{
				money += tmp.b*1.0/tmp.a;
				sum -= tmp.b;
			}
		}
	}
	printf("%.2f\n",money);
	return 0;
}

O - 优先队列 CodeForces - 948C

1.题目描述:
Alice likes snow a lot! Unfortunately, this year’s winter is already over, and she can’t expect to have any more of it. Bob has thus bought her a gift — a large snow maker. He plans to make some amount of snow every day. On day i he will make a pile of snow of volume Vi and put it in her garden.

Each day, every pile will shrink a little due to melting. More precisely, when the temperature on a given day is Ti, each pile will reduce its volume by Ti. If this would reduce the volume of a pile to or below zero, it disappears forever. All snow piles are independent of each other.

Note that the pile made on day i already loses part of its volume on the same day. In an extreme case, this may mean that there are no piles left at the end of a particular day.

You are given the initial pile sizes and the temperature on each day. Determine the total volume of snow melted on each day.

Input
The first line contains a single integer N (1 ≤ N ≤ 105) — the number of days.

The second line contains N integers V1, V2, …, VN (0 ≤ Vi ≤ 109), where Vi is the initial size of a snow pile made on the day i.

The third line contains N integers T1, T2, …, TN (0 ≤ Ti ≤ 109), where Ti is the temperature on the day i.

Output
Output a single line with N integers, where the i-th integer represents the total volume of snow melted on day i.

Examples
Input
3
10 10 5
5 7 2

Output
5 12 4

Input
5
30 25 20 15 10
9 10 12 4 13

Output
9 20 35 11 25

Note
In the first sample, Bob first makes a snow pile of volume 10, which melts to the size of 5 on the same day. On the second day, he makes another pile of size 10. Since it is a bit warmer than the day before, the first pile disappears completely while the second pile shrinks to 3. At the end of the second day, he has only a single pile of size 3. On the third day he makes a smaller pile than usual, but as the temperature dropped too, both piles survive till the end of the day.

2.题意:
大概就是一个人买了个造雪器在院子里造雪(大夏天的浪费能源(“咆哮状”),杀狗哭唧唧。),男的会每天造一个雪人,但是雪人儿顶不住阳光的啦,就会融化啦,我们就是求在给定的天数里我们每天能融掉的雪的量啦。

3.思路:
主要是用前缀和来表示温度的累加,以及用优先队列来表示雪人。为什么用前缀和呢?是由于每次气温导致的变化不一样,逐一去减的话,你每次都要清空队列再加进去,很麻烦。
不如用等效的思想,把融化量累积起来——前缀和。我们用前缀和让最小的融掉然后循环判断,这样就可以保证融掉的和没有融掉的雪量的正确性,也不用每次清空这么麻烦(毕竟出队就代表融掉了)。

4.代码:

//O - 优先队列 
#include<iostream>
#include<stack>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
	//freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
	long long n,tmp,ans=0;
	vector<long long> v,sumtep;//累计的温度,前缀和 
	v.push_back(0);
	sumtep.push_back(0);
	cin>>n;
	priority_queue<long long,vector<long long>,greater<long long> > q;
	//读入 
	for(long long i=1;i<=n;++i)
	{
		cin>>tmp;
		v.push_back(tmp);
	}
	for(long long i=1;i<=n;++i)
	{
		cin>>tmp;
		sumtep.push_back(sumtep[i-1]+tmp); 
	} 
	for(long long i=1;i<=n;++i,ans=0)
	{
		q.push(v[i]+sumtep[i-1]);
		while(!q.empty()&&sumtep[i]>=q.top())
		{
			ans+=q.top()-sumtep[i-1];//如果我们如今最小的雪人顶不住前几天的温度,就把它完全融掉 
			q.pop();
		}
		ans+=q.size()*(sumtep[i]-sumtep[i-1]);//剩下的没有完全融掉的雪人,就按气温来计算 
		if(i==1) cout<<ans;
		else cout<<" "<<ans;
	}
	return 0;
}

//剩下的题目我会补的QAQ!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值