首页 > 其他分享 >CF1442D Sum

CF1442D Sum

时间:2024-01-02 17:22:05浏览次数:30  
标签:int CF1442D Sum mid 数组 include dp size

题意

给定 \(n\) 个递增数组。

\(k\) 次操作,每次你可以选择一个数组,使 \(ans\) 加上数组的第一个数,并删除。

问最大化的 \(ans\) 的值。

Sol

考虑当前选择的方案如何变得更优。

不难想到,如果当前有两个数组没有选满,则一定可以调整到其中一个变成空的方案,而使得答案不劣。

所以,不难想到结论就是最优方案只有一个数组没有选满。

枚举该数组,并对剩下的数组做 \(01\) 背包。

时间复杂度 \(O(n ^ 2k)\)。

发现分块显然可做,时间复杂度 \(O(n \sqrt n k)\)

考虑更优的做法。

设计这样一种分治:\((l, r)\) 表示不选 \([l, r]\) 之间的数组的方案数。

每次分治先将 \([l, mid]\) 加入 \(dp\),然后递归 \((mid + 1, r)\)。

将 \(dp\) 数组清空,再将 \([mid + 1, r]\) 加入 \(dp\),递归 \((l, mid)\)。

做完了,时间复杂度 \(O(nk \log n)\)。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <vector>
#define int long long
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
	int p = 0, flg = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') flg = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		p = p * 10 + c - '0';
		c = getchar();
	}
	return p * flg;
}
void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}
const int N = 1e6 + 5, M = 3005;

array <vector <int>, M> s;
array <int, M> f;

int ans;

array <array <int, N>, 35> isl;

void solve(int l, int r, int n, int k, int d) {
	if (l == r) {
		for (int i = 0; i <= min((int)s[l].size() - 1, k); i++)
			ans = max(ans, s[l][i] + f[k - i]);
		return;
	}
	int mid = (l + r) >> 1;
	for (int i = 0; i <= k; i++)
		isl[d][i] = f[i];
	for (int i = l; i <= mid; i++)
		for (int j = k; j >= (int)s[i].size() - 1; j--)
			f[j] = max(f[j - s[i].size() + 1] + s[i].back(), f[j]);
	solve(mid + 1, r, n, k, d + 1);
	for (int i = 0; i <= k; i++)
		f[i] = isl[d][i];
	for (int i = mid + 1; i <= r; i++)
		for (int j = k; j >= (int)s[i].size() - 1; j--)
			f[j] = max(f[j - s[i].size() + 1] + s[i].back(), f[j]);
	solve(l, mid, n, k, d + 1);
	for (int i = 0; i <= k; i++)
		f[i] = isl[d][i];
}

signed main() {
	int n = read(), k = read();
	for (int i = 1; i <= n; i++) {
		int x = read();
		s[i].push_back(0);
		while (x--) {
			int y = read();
			s[i].push_back(s[i].back() + y);
		}
	}
	solve(1, n, n, k, 0);
	write(ans), puts("");
	return 0;
}

标签:int,CF1442D,Sum,mid,数组,include,dp,size
From: https://www.cnblogs.com/cxqghzj/p/17940904

相关文章

  • P10033 「Cfz Round 3」Sum of Permutation
    原题链接基础赛唯一写了的题,因为我喜欢构造!事实上的确有点麻烦了,应该会有更好的做法。但是自我感觉这个思维很连贯,因为这就是我做题时思路的写照。记\(p_{pos1}=1,p_{posn}=n\)。首先可以构造\(a_i\getsp_i+1\)这样一定满足第二个限制,但是当\(p_i=n\)时不满足第一个限......
  • AtCoder Regular Contest 168 E Subsegments with Large Sums
    洛谷传送门AtCoder传送门尝试二分答案,问题变为要求恰好选\(x\)段\(\ges\),最大化选的段数。发现我们不是很会算段数的\(\max\),因为要求段不重不漏地覆盖\([1,n]\)。考虑给每个\(\ges\)段\([l,r]\)一个\(r-l\)的代价,于是变成了算代价的\(\min\)。此时不再要求......
  • POLIR-Int-Generative AI in 2024: The 6 most important consumer tech trends for n
    GenerativeAIin2024:The6mostimportantconsumertechtrendsfornextyearQualcommexecutivesrevealkeytrendsinAI,consumertechnologyandmoreforthefutureDEC15,2023SnapdragonandQualcommbrandedproductsareproductsofQualcommTechnol......
  • kaggle Open Problems – Single-Cell Perturbations 1st & 2nd place solution summa
    Leaderboard:https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/leaderboard2ndSolution:https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/discussion/458738Code:https://github.com/Eliorkalfon/single_ce......
  • 『LeetCode』1. 两数之和 Two Sum
    『1』暴力法classSolution{//BruteForce//TimeComplexity:O(n^2)//SpaceComplexity:O(1)publicint[]twoSum(int[]nums,inttarget){for(inti=0;i<nums.length;i++){for(intj=i+1;j<nums.length......
  • 陶建辉应邀参与 TOP100Summit,“工程师文化”演讲引发热议
    在AGI时代,数字化成为组织形态的重要特征,它可以帮助组织实现上下一致的目标和信息的高频传递,从而实现战略目标的协同和敏捷进化。在这样的大背景下,开发者们面临的实际挑战是如何避免技术和业务之间的割裂。12月14-17日,由msup和微上信息技术研究院联合主办的第十二届“TOP100......
  • 1 + np.nan # nan sum([1, np.nan]) # nan
    1+np.nan#nansum([1,np.nan])#nannp.sum([1,np.nan])#nanhttps://blog.51cto.com/u_16055028/6177557PythonPandaspivot_table透视表计数numpy.sum()是NumPy库中的一个函数,用于计算数组中所有元素的总和¹²³⁴⁵。以下是该函数的基本语法:numpy.sum(a,axis=N......
  • [ARC107F] Sum of Abs
    [ARC107F]SumofAbs发现点数比较少,考虑最小割我们最大可能的答案为\(\sum|b_i|\),现在考虑减去多余答案首先点可以不选,于是拆点,之间边权为\(a_i+|b_i|\)钦定割完之后,和\(S\)连通的点最终取正数,和\(T\)连通的点最终取负数,于是如果\(b_i\ge0\),那就从源点向他连\(2b_i......
  • Sum of XOR Functions 题解
    题意给定一个数\(n\)和一个包含\(n\)个数的序列\(a\),求出以下式子模\(998244353\)的值:\(\sum_{i=1}^{n}\sum_{j=i}^{n}f(i,j)\times(j-i+1)\)。其中\(f(i,j)\)的值为\(a_{i}\oplusa_{i+1}\oplusa_{i+2}\oplus...\oplusa_{j}\)。思路首先我们可以考虑这道题的......
  • 【CF1698C】3SUM Closure
    题目大意:判断一个数组是否满足其中任意三个元素之和均为数组的元素如果一个元素出现的次数大于三,那么我们将这个元素的数量减到三,答案不会变。另外,我们发现,如果数组至少中有三个正数,或者至少有三个负数,那么答案一定为NO。如果上面的条件不满足,那么现在这个数组里的元素最多只......