YY 的工作
题目背景
是一个勤工俭学的好孩子,暑假的时候他来到一个旅游公司打工赚外快(冲
STEAM )。假期来景点游玩的人非常多,于是他的老板想调整一下票价,好让游客们满
意,同时又要尽可能多赚些钱。按照正常的操作,这个任务,没错,又到了 YY 头上,于
是 YY 又来找你帮忙了 ......
YY
题目描述
这个公司一共管理着 n 个景点,每个景点的票价和参观人数呈一个固定的函数关系。具
体地说,如果该景点的票价为 x ,则该景点会有 a i − b i × x 个游客来游玩。那么在所有
景点的总票价不超过 m 的情况下,请你安排一个方案使得赚到的钱最多。输入格式
从文件 work.in 中读入
第一行两个正整数 n, m ,含义如上。
接下来 n 行每行两个正整数 a i , b i 表示每个景点的参数。
输出格式
输出到 work.out 文件中
共一行,表示最多能赚到的钱数。
样例
输入
2 4
50 2
40 1
输出
171
数据范围
对于 100% 的数据: 1 ≤ n, m ≤ 100000, 1 ≤ a i , b i ≤ 100000
对于 20% 的数据: 1 ≤ n, m ≤ 200
对于另外 10% 的数据: m = 1
对于另外 30% 的数据: a − b ≤ 1, m ≤ n
这道题的思路其实挺明显的,我们不去想怎么直接给每个景点分配多少票价,而是将票价一个一个的给景点。
这其中就有贪心的思想,我们保存每次最大可以多获得多少价格(函数知识),用堆来维护就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define il inline
#define db double
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
y=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*y;
}
struct node
{
int b,v;
}no[1000045],heap[1000045];
int size;
il void push(node x)
{
heap[++size]=x;
int now=size,next;
while(now!=1)
{
next=now>>1;
if(heap[next].v>heap[now].v)
break;
swap(heap[next],heap[now]);
now=next;
}
}
il void pop()
{
heap[1]=heap[size--];
int now=1,next;
while(now<<1<=size)
{
next=now<<1;
if(heap[next+1].v>heap[next].v)
next++;
if(heap[next].v<heap[now].v)
break;
swap(heap[next],heap[now]);
now=next;
}
}
int main()
{
freopen("work.in","r",stdin);
freopen("work.out","w",stdout);
int n=gi(),m=gi();
int x,y;
for(int i=1;i<=n;i++)
{
x=gi(),y=gi();
if(x-y>0)
{
no[i].b=y;
no[i].v=x-y;
push(no[i]);
}
}
ll ans=0;
for(int i=1;i<=m;i++)
{
if(!size)
break;
node now=heap[1];
pop();
ans+=now.v;
now.v-=(now.b<<1);
if(now.v<=0)
continue;
push(now);
}
printf("%lld\n",ans);
return 0;
}
PEACE

浙公网安备 33010602011771号