题目描述
小可可在小区里安装了一个电动汽车充电桩,将自家充电桩的空闲时间开放给其他电动车用户付费使用。这种共享充电模式能充分提高闲置充电桩的利用率既可以让小可可获得收益,也缓解了其他车主的充电焦虑。现在共有n个使用充电桩的申请,编号从0到n−1。小可可将按编号依次处理所有申请,每个申请Qi(0≤i≤n−1)信息包含两个正整数ai和bi。
对于申请Qi小可可有两种处理策略:
(1)接受申请Qi,将获得ai元收益,但必须放弃接下来的bi个申请。
(2)拒绝申请Qi,没有收益,继续处理下一个申请。
请帮助小可可计算出共享充电桩能获得的最大收益。
输入格式
共n+1行,第一行一个整数n,表示使用充电桩的申请数量。
接下n行,第i行包含两个正整数ai和bi。表示接受申请Qi,将获得ai元收益,但必须放弃接下来的bi个申请。
输出格式
一行一个正整数,表示小可可共享充电桩获得的最大收益。
输入样例
4
3 2
5 4
4 4
3 5
输出样例
6
数据范围与提示
【说明】
样例解释:小可可共收到4个使用充电桩的申请,最佳策略为接受申请0和申请3。
(1)接受申请0,获得3元收益,但接下来2个申请都必须拒绝。
(2)接受申请3,获得3元收益。
总收益为:3元+3元=6元。
【数据范围】
1 ≤ n ≤ 10^6,1 ≤ ai , bi ≤ 10^5。
OK啊,这边也是你们最最最最。。。最喜欢的代码环节了(直接复制代码食不食?)
最大上升子序列和 线性DP讲解 奥赛一本通_哔哩哔哩_bilibili
不会最大上升子序和的给爷学!!!
#include<bits/stdc++.h>
using namespace std;
long long a[1000001],b[1000001],f[1000001];
//注注注意是10^6,用longlong防止溢出。。。
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i],&b[i]);
//这点时间很重要。。。
f[n]=a[n];
for(int i=n-1;i>=1;i--)
{
f[i]=max(a[i],f[i+1]);
//初始判断。。。
if(i+b[i]+1<=n)//注意不仅i+b[i],还要加1;
//进阶判断
f[i]=max(f[i],f[i+b[i]+1]+a[i]);
}
printf("%lld",f[1]);
return 0;
}
给大家附赠map容器图