[CF1442D] Sum

前言

做过原题的和没做过的都切了,只有我拉了大胯。

题目

洛谷

CF

讲解

这道题我在一开始方向就错了,我以为是什么奇技淫巧优化 DP,可以把 \(O(nk^2)\) 优化成 \(O(nk)\) 或者 \(O(nk\log_2k)\)

先丢一个结论:

  • 至多存在一个数组没取满。

证明的话假设有两个没取满,大的那个增多,小的那个减少,显然不劣。典型易证难想结论。

接下来考虑枚举没取满的那个数组,我们希望得到其它数组的背包结果。

前后缀拼起来并没有什么用,但是这玩意竟然可以分治!是个人均都会的trick,被开除人籍了

大概就是你先记录一下当前背包状态,把前半部分背包一下,后半部分丢进去处理。

出来之后把背包赋值为之前记录的状态,然后把后半部分背包一下,前半部分丢进去处理。

到最后一层的时候就可以直接更新答案了。

很牛逼啊,这是 \(O(nk\log_2n)\)

代码

还没懂看看代码就懂了
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 3005;
int n,k;
LL a[MAXN][MAXN],dp[MAXN],tmp[30][MAXN],ans;

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

void solve(int l,int r,int d)
{
	if(l == r)
	{
		for(int i = 0;i <= a[l][0];++ i) 
			ans = Max(ans,dp[k-i]+(i == 0 ? 0 : a[l][i]));
		return;
	}
	int mid = (l+r) >> 1;
	
	for(int i = 0;i <= k;++ i) tmp[d][i] = dp[i];
	for(int i = l;i <= mid;++ i)
		for(int j = k;j >= a[i][0];-- j)
			dp[j] = Max(dp[j],dp[j-a[i][0]]+a[i][a[i][0]]);
	solve(mid+1,r,d+1);
	
	for(int i = 0;i <= k;++ i) dp[i] = tmp[d][i];
	for(int i = mid+1;i <= r;++ i)
		for(int j = k;j >= a[i][0];-- j)
			dp[j] = Max(dp[j],dp[j-a[i][0]]+a[i][a[i][0]]);
	solve(l,mid,d+1);
}

int main()
{
//	freopen("factory.in","r",stdin);
//	freopen("factory.out","w",stdout);
	n = Read(); k = Read();
	for(int i = 1;i <= n;++ i)
	{
		a[i][0] = Read();
		for(int j = 1;j <= Min(a[i][0],0ll+k);++ j) a[i][j] = (j == 1 ? 0 : a[i][j-1]) + Read();
		for(int j = k+1;j <= a[i][0];++ j) Read();
		a[i][0] = Min(a[i][0],0ll+k);
	}
	solve(1,n,0);
	Put(ans,'\n');
	return 0;
}
posted @ 2021-11-14 15:42  皮皮刘  阅读(27)  评论(0编辑  收藏  举报