P6023 走路 题解
简要题意:
小 \(A\) 为了防止猝死,在 \(n\) 天中准备走 \(\leq m\) 步,给出若干奖励政策形如 “第 \(p\) 天走完 \(q\) 步,那么该天 接下来走的每一步 都会增加 \(1\) 分”;奖励可以累加。求最高分数。
先庆祝一下:
看到了吧,我在这题的评测排名中排 \(\text{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\times c_1\) 分(后面可能还有其他的激励措施)。同时,由于同一天内每一步获得的分数是递增(非严格)的,我们有
\[b_1+a_2\times c_1\ge b_1+a_2\times c_2\ge 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\n",ans);
return 0;
}
简易的代码胜过复杂的说教。