P9097 [PA 2020] Elektrownie i fabryki 题解
_Spectator_ · · 题解
可能更好的食用体验
{\color{#00CD00}\text{思路}}
考虑
它的含义是:枚举一个分界点
写成代码是这样的:
memset(f, 0x3f, sizeof(f)), f[0] = 0;
for(int i=1; i<=n; i++){
for(int j=1; j<=i; j++){
if(s[i] - s[j-1] >= 0) f[i] = min(f[i], f[j-1] + i - j);
}
}
朴素的
具体地,先将所有的
{\color{#00CD00}\text{代码}}
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
long long n, s[N], rk[N];
int a[N], f[N];
struct BIT{
int c[N], lowbit(int x){return x & -x;}; BIT(){memset(c, 0x3f, sizeof(c));}
void update(int x, int k){while(x < N) c[x] = min(c[x], k), x += lowbit(x);}
int query(int x){int s = N; while(x) s = min(s, c[x]), x -= lowbit(x); return s;}
} t;
signed main(){
cin.tie(nullptr) -> sync_with_stdio(false);
cin >> n;
for(int i=1; i<=n; i++) cin >> a[i], rk[i] = s[i] = s[i-1] + a[i];
sort(rk, rk + 1 + n); int k = unique(rk, rk + 1 + n) - rk;
for(int i=0; i<=n; i++) s[i] = lower_bound(rk, rk + 1 + k, s[i]) - rk + 1;
t.update(s[0], 0);
for(int i=1; i<=n; i++){
f[i] = t.query(s[i]) + i - 1;
t.update(s[i], f[i] - i);
}
cout << (f[n] > n ? -1 : f[n]);
return 0;
}