题目:https://citel.bjtu.edu.cn/acm/problem/1882
前不久 sqy 老师花了大价钱,去做了一个帅气的锡纸烫。有着商业眼光的 sqy 一下子发现了大商机,于是他自己开了一家美容美发店。
sqy 找了刚刚做完纹理烫的大预言家 cbj 预测了未来,发现每个顾客都只在白天来美发店,并且第一次来店里的时候都会充一次价值 x i x_i xi 的卡,然后从第二天开始,每天白天都会来这里打理头发,而 sqy 仅收取成本价 1 元钱来吸引顾客,直到把卡掏空为止,这个顾客就再也不会回来。
黑心商人 sqy 找大预言家要来了每个顾客的充卡时间和充值金额,他准备在某一天晚上跑路,他想知道自己最多能卷走多少钱。
输入数据
第一行包括一个整数 n(1≤n≤
1
0
5
10^5
105) 表示有 n 个顾客。
接下来共 n 行,每i+1行包括两个整数
x
i
x_i
xi,
y
i
y_i
yi 表示第
x
i
x_i
xi 天一个顾客来充值了 yi 元 (1≤
x
i
x_i
xi≤
1
0
6
10^6
106,0≤
y
i
y_i
yi≤
2
31
−
1
2^{31}−1
231−1)。
输出数据
输出一行包括一个整数 ans,表示 sqy 最多能卷走多少钱。
样例输入
5
1 5
2 5
3 5
4 5
5 5
样例输出
15
//在第五天的时候,第一个人消费4元还剩1元,第二个人消费3元还剩2元,第三个人消费2元还剩3元,第四个人消费1元还剩4元,第五个人还没有开始消费就被卷钱跑路了。
分析
核心是构建递推公式:
a
i
+
1
=
a
i
+
m
i
+
1
−
(
n
i
−
b
i
)
a_{i+1} = a_{i} + m_{i+1} - (n_i-b_i)
ai+1=ai+mi+1−(ni−bi)
其中:
a
i
+
1
a_{i+1}
ai+1是第i+1天跑路时的累计收益;
m
i
+
1
m_{i+1}
mi+1是当天的收益;
(
n
i
−
b
i
)
(n_i-b_i)
(ni−bi)是当天的支出,也就是美发店中剩下的人数(累计来的人数-累计走的人数,通过遍历数组计算得到)。
代码
//
// Created by ZixinQin on 2021/9/17.
//
# include <iostream>
# include <cstdio>
# include <algorithm>
using namespace std;
struct Record{
int come;
int charge;
int leave;
}re[1000100];
int benefit[1000100];
int come[1000100];
int leave[1000100];
int charge[1000100];
int main() {
int N;
//cin>>N;
scanf("%d", &N);
int max_day = 0;
int max_charge = 0;
for (int i = 1; i <= N; ++i) {
int day, charge;
//cin>>day>>charge;
scanf("%d %d", &day, &charge);
re[day].charge += charge;
re[day].come += 1;
if(day+charge<1000100)
re[day+charge].leave += 1;
if (day > max_day)
max_day = day;
if (charge > max_charge)
max_charge = charge;
}
come[0] = 0;
leave[0] = 0;
for(int i=1;i<=max_day;i++){
charge[i] = re[i].charge; // charge in
come[i] = come[i-1] + re[i].come;// total come
leave[i] = leave[i-1] + re[i].leave; // total leave
//cout<<i<<" "<<charge[i]<<" "<<come[i]<<" "<<leave[i]<<endl;
}
benefit[1] = charge[1];
come[0] = 0;
leave[0]= 0;
int max_benefit = 0;
for(int i=2;i<=max_day;i++){
benefit[i] = benefit[i-1] + charge[i] - (come[i-1]-leave[i-1]);
//cout<<benefit[i]<<endl;
if(benefit[i]>max_benefit)
max_benefit = benefit[i];
}
cout<<max_benefit<<endl;
}