简要题意:
小 (A) 为了防止猝死,在 (n) 天中准备走 (leq m) 步,给出若干奖励政策形如 “第 (p) 天走完 (q) 步,那么该天 接下来走的每一步 都会增加 (1) 分”;奖励可以累加。求最高分数。
先庆祝一下:
看到了吧,我在这题的评测排名中排 ( ext{Rank6}),(98ms) 可还行?
首先本题就在于,每个政策都是对应 (1) 天而言的,所以一个贪心思想就是,考虑把所有步数都放在同 (1) 天。
然后就AC了可海星
如何证明?
假设,枚举所有天考虑 (n) 步全部放在该天的答案中,第 (x) 天的答案为 (y) 是最大值。
那么,有没有可能,将这 (n) 天的部分(可能为 (n))分给别的天,然后达到更优呢?显然是不可能的。
因为当前天已经是最优答案,这里出题人给出了解答:
假如有两天,比如第一天和第二天都走了路,设两天走的步数、已获得积分、接下来每步获得的积分分别为 (a_1,a_2,b_1,b_2,c_1,c_2),且 (c_1 geq c_2)
如果我们把所有步数都放到第一天,那么我们至少会获得 (b_1+a_2 imes c_1) 分(后面可能还有其他的激励措施)。同时,由于同一天内每一步获得的分数是递增(非严格)的,我们有
[b_1+a_2 imes c_1ge b_1+a_2 imes c_2ge b_1+b_2
]
所以,如果分数最大,那么必定所有步数都是放在同一天。
对的没错,这个证明简单至极,话说都放在同一天不是更容易猝死了么
然后,对于每个 “(x) 天 (y) 步的奖励”,肯定会对第 (x) 天增加 (n-y) 的贡献(因为都在第 (x) 天了),把贡献存在数组里打擂即可。
时间复杂度:(O(m)).
实际得分:(100pts).
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+1;
inline ll read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
ll x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll n,m,k,a[N];
ll ans=0;
int main(){
n=read(); m=read(); k=read();
for(int i=1,p;i<=k;i++) p=read(),a[p]+=(n-read()),ans=max(ans,a[p]);
printf("%lld
",ans);
return 0;
}