MLE求助
查看原帖
MLE求助
780641
WD2c0mP楼主2023/1/29 08:33

这题在别的限制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;
}
2023/1/29 08:33
加载中...