2 条题解

  • 0
    @ 2025-7-2 14:30:47

    这个题我可能想复杂了

    w[l][r]w[l][r][l,r][l,r]这个区间内一个背包可以装的最大数量,这个东西显然可以用反贪弄

    这样我们的题目就变为选择mm个区间使得权值最大

    考虑dpdp

    f[i][j]f[i][j]为前ii个数中一定要选ii这个点的前提下选jj段的最大值

    f[i][j]=max(f[i1][j],f[k][j1]+w[k+1][i])f[i][j] = max(f[i-1][j],f[k][j-1]+w[k+1][i])

    其中 0<=k<i0 <= k < i

    然后就做完了

    code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e3 + 10;
    
    int n, k, m, a[N], w[N][N], f[N][N];
    
    void read() {
    	cin >> n >> k >> m;
    	for(int i = 1; i <= n; i++) cin >> a[i];
    }
    
    priority_queue<int> q;
    
    void compute() {
    	for(int l = 1; l <= n; l++) {
    		int now = 0;
    		for(int r = l; r <= n; r++) {
    			if(now + a[r] <= k) {
    				now += a[r];
    				q.push(a[r]);
    			} else {
    				if(q.size() && a[r] < q.top()) {
    					now -= q.top();
    					q.pop();
    					now += a[r];
    					q.push(a[r]);
    				}
    			}
    			w[l][r] = q.size();
    		}
    		while(q.size()) q.pop();
    	}
    	for(int i = 1; i <= n; i++) {
    		for(int p = 1; p <= m; p++) {
    			for(int j = 0; j < i; j++) {
    				f[i][p] = max(max(f[i-1][p],f[j][p-1]+w[j+1][i]),f[i][p]);
    			}
    		}
    	}
    	cout << f[n][m];
    }
    
    int main() {
    	read();
    	compute();
    	return 0;
    }
    

    警钟

    用优先队列时,一定要注意判断队里面有没有元素!!!不然会RE

    信息

    ID
    306
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    (无)
    递交数
    68
    已通过
    14
    上传者