- 题目大意: 给出长度为\(n\)的序列\(d_i\)和生命值\(H\),每次到达该位置后生命值更新为\(H+d_i\),求\(H\)首次为零的时段
- 思路: 首先想到先跑\(\ | \frac{H}{\sum{d_i}}\ | -1\)次然后跑最后一轮,但是序列的最小前缀可能远远小于\(\sum{d_i}\),所以跑\(\ | \frac{H}{\sum{d_i}}\ | - \frac{minsum}{\sum{d_i}}\)次,然后暴力跑到\(H\)为0即可
#include#define ll long long #define FOR(i,n) for(int i =1; i <= n;++i ) #define FOR0(i,n) for(int i =0; i < n;++i ) #define inf 0x3f3f3f3fusing namespace std; const int maxn = 2*1e6+10; ll H;int n;int a[maxn]; int main(){ cin >>H >> n; ll tot = 0; ll mps = 0; ll HH = H; FOR(i,n){ cin >> a[i]; tot += a[i]; HH+= a[i]; mps = min(mps,tot); a[i+n] = a[i]; if(HH<=0){ cout < << endl; exit(0); } } if(tot >=0){ cout << -1 << endl; }else{ ll len = H/(-1*tot); len = max(len-mps/tot,0LL); H+=len*tot; len *= n; while(H>0){ FOR(i,n+n){ H+= a[i]; if(H<=0){ len += i; break; } } if(H>0) len += n+n; } cout << len<
被卡了两次,贪心也不能贪过头了