简化题意
给定 \(H,n\) 和一个长度为 \(n\) 的序列 \(d\),求一个最小的 \(m\) 使得 \(H+\sum\limits_{i=1}^{m}d_{(i-1) \bmod n+1} \le 0\)。
解法
将式子移项后得到 \(\sum\limits_{i=1}^{m}-d_{(i-1) \bmod n+1} \ge H\)。
将 \(\sum\limits_{i=1}^{m}-d_{(i-1) \bmod n+1}\) 拆成 \(x\sum\limits_{i=1}^{n}-d_{i}\) 和 \(\sum\limits_{i=1}^{y}-d_{i}\) 两部分,即 \(m=xn+y\)。枚举 \(y \in [1,n]\),则对应的 \(\min \{ x \}=\left\lceil \frac{H-\sum\limits_{i=1}^{y}-d_{i}}{\sum\limits_{i=1}^{n}-d_{i}} \right\rceil\)。
最终,有 \(\min\limits_{y=1}^{n} \{ \left\lceil \frac{H-\sum\limits_{i=1}^{y}-d_{i}}{\sum\limits_{i=1}^{n}-d_{i}} \right\rceil n+y \}\) 即为所求,注意精度影响,优化同 [ABC345B] Integer Division Returns 。
- 注意判无解时要对第一轮进行特判。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
ll d[200010],sum[200010];
int main()
{
ll h,n,ans=0x7f7f7f7f7f7f7f7f,flag=0,i;
cin>>h>>n;
for(i=1;i<=n;i++)
{
cin>>d[i];
sum[i]=sum[i-1]-d[i];
if(sum[i]>=h&&flag==0)
{
flag=1;
cout<<i<<endl;
}
}
if(flag==0)
{
if(sum[n]<=0)
{
cout<<"-1"<<endl;
}
else
{
for(i=1;i<=n;i++)
{
ans=min(ans,(h-sum[i]+sum[n]-1)/sum[n]*n+i);
}
cout<<ans<<endl;
}
}
return 0;
}
标签:CF1141E,limits,题解,sum,long,flag,Battle,bmod,define
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18213436