这题在别的限制512M内存的OJ上已经过了,但洛谷是125MB,请问怎么改成滚动数组?
#include <bits/stdc++.h>
#define ll int
#define mod 10007
using namespace std;
int a[50010], dp[50010][1010], n, m;
int dpsum[50010][1010], ret;
inline bool check(ll mid) {
ll sm = 0;
int cnt = 0;
for (int i = 1; i <= n; i ++) {
if (a[i] > mid)
return false;
if (sm + a[i] > mid) {
cnt ++;
sm = 0;
}
sm += a[i];
}
return cnt <= m;
}
inline void READ() {
scanf("%d %d",&n,&m);
for (int i = 1; i <= n; i ++){
scanf("%d",&a[i]);
}
}
inline void BINARY_SEARCH() {
ll l = 1, r = 1145141919810, mid;
while (l <= r) {
mid = (l + r) >> 1;
if (check(mid)) {
ret = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
cout << ret << " ";
}
inline int __DP(int rett) {
/*
·状态:dp[i][j]表示前i根木棍分成j组的方案数
·初始化:dp[i][1] = sum[i]
·转移:
设k是sum[i] - sum[k] ≤ ret最小的k
dp[i][j] = ∑ dp[l][j - 1] (k <= l < i)
·优化 ·dp数组前缀和
*/
dp[0][0] = dpsum[0][0] = 1;
int k = 0,xum = 0;
for (int i = 1; i <= n; i ++) {
xum += a[i];
while (xum > rett){
k ++;
xum -= a[k];
}
if (k) {
for (int j = 1;j <= m + 1;j ++)
dp[i][j] = (dpsum[i - 1][j - 1] - dpsum[k - 1][j - 1] + mod) % mod;
}
else {
for (int j = 1;j <= m + 1;j ++)
dp[i][j] = dpsum[i - 1][j - 1] % mod;
}
for (int j = 0;j <= m + 1;j ++){
dpsum[i][j] = (dpsum[i - 1][j] + dp[i][j]) % mod;
}
}
ll sum = 0;
for (int i = 1; i <= m + 1; i ++) {
sum += dp[n][i];
sum %= mod;
}
return sum;
}
int main() {
READ();
BINARY_SEARCH();
cout << (__DP(ret) - __DP(ret - 1) + mod) % mod;
return 0;
}