Description
Solution
第一问二分答案,第二问就是一个简单的DP,前缀和优化一下就行。
Code
const int N = 5e4 + 10;
const int ha = 1e4 + 7;
int a[N], f[N], s[N], sf[N], nxt[N];
int n, m;
bool check(int x) {
int l = 1, r = 0, ans = 0;
while (r <= n) {
while (r <= n && s[r] - s[l - 1] <= x) r++;
// if (x == 1) printf("%d %d
", l, r);
ans++;
if (r > n) break;
if (l == r) return false;
l = r;
}
return ans <= m;
}
int solve(int x) {
f[1] = 1;
for (int i = 1; i <= n; ++i) sf[i] = 1;
int ans = 0;
int k = n - 1;
for (int j = n; j > 1; --j) {
while (k > 0 && s[j] - s[k] <= x) k--;
nxt[j] = k;
}
for (int i = 1; i <= m; ++i) {
for (int j = n; j > 1; --j) {
f[j] = 0;
f[j] = (sf[j - 1] - sf[nxt[j]] + ha);
if (f[j] >= ha) f[j] -= ha;
}
f[1] = sf[1] = 0;
for (int j = 2; j <= n; ++j) {
sf[j] = (sf[j - 1] + f[j]);
if (sf[j] >= ha) sf[j] -= ha;
}
(ans += f[n]) %= ha;
}
return ans;
}
int main() {
scanf("%d%d", &n, &m);
m++;
n++;
for (int i = 2; i <= n; ++i) {
scanf("%d", &a[i]);
s[i] = s[i - 1] + a[i];
}
int l = 0, r = s[n], ans = -1;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
printf("%d %d
", ans, solve(ans));
return 0;
}