返回顶部

Codeforces Round #765 (Div. 2)题解

作者:@cherish.
课程学习内容为作者从学校的PPT处摘抄,仅供自己学习参考,若需转载请注明出处:https://www.cnblogs.com/cherish-/p/15796912.html


目前补到C

A. Ancient Civilization

题目描述:给你n个长度为l的二进制数组a,这些二进制数以十进制的形式给你,让你求一个最小的l位二进制数x,定义d(x,y)表示两个数字二进制表示下不同位的个数,如10011100d=2。求最小的x使和式i=1nd(ai,x)的值最小。

思路:显然将ai的每一位拆开,若ai的第j位的数量小于n的一半,那么对答案的贡献为0 << j否则对答案的贡献是1 << j

时间复杂度:O(Tnl)

参考代码:

int n, l, a;
void solve() {
	cin >> n >> l;
	vector<int> cnt(l, 0);
	for (int i = 1; i <= n; ++i) {
		cin >> a;
		for (int j = 0; j < l; ++j) cnt[j] += a >> j & 1;
	}
	int res = 0;
	for (int i = 0; i < l; ++i) {
		int dx = 2 * cnt[i] > n;
		res |= dx << i;
	}
	cout << res << '\n';
	return;
}

B. Elementary Particles

题目描述:给你一个长度为n的数组a,求最长的整数k,使得数组a存在两个不同的长度为k的子段b,c,且1ik,使得bi=ci

数据范围:1T100,2n1.5×105,1ai1.5×105,n3×105

思路:考虑到只需要存在即可,我们可以将相同数字的下标存下来,然后遍历每一个相同的数字,若当前数字个数小于2,跳过,否则枚举相邻两个相同的数字,假设其下标为u,v,则其向左边最多取min(u,v)(包含当前下标),向右边最多取min(nu,nv)(不包含当前下标),那么最终的长度就为

min(u,v)+min(nu,nv)

对于所有的取最大值即可。注意为了不重复遍历需要进行去重。

时间复杂度:O(Tnlogn)

空间复杂度:O(n)

参考代码:

const int N = 2e5 + 5;
vector<vector<int>>g(N);
int n;
void solve() {
	cin >> n;
	vector<int>a(n + 1, 0);
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		g[a[i]].push_back(i);
	}
	std::sort(a.begin(), a.end());
	int m = unique(a.begin(), a.end()) - a.begin();
	int res = -1;
	for (int i = 1; i < m; ++i) {
		if (g[a[i]].size() < 2) continue;
		int len = g[a[i]].size();
		for (int j = 1; j < len; ++j) {
			int u = g[a[i]][j - 1], v = g[a[i]][j];
			int lr = min(u, v), rs = min(n - v, n - u);
			res = max(res, lr + rs);
		}
	}
	cout << res << '\n';
	for (int i = 1; i < m; ++i) g[a[i]].clear();
	return;
}

C. Road Optimization

题目描述:给你一个长度为n的数组a,和一个长度为n+1的数组d,(注:实际给你的只有n个,dn+1=l)。其价值的计算公式为:

f=i=1n(di+1di)ai

现让你删除其中的不超过k个元素,求min{f}

数据范围:1n500,1l105,0kn1,1ai104

思路:比较显然的dp,定义状态fi,j表示以第i个数结尾删除j个数字后所能取得的最小值,则最终答案为:

mini=0kfn,i

考虑如何转移,假设枚举(i,j]表示要删除该区间内的所有元素,则此时区间对答案的贡献为(dj+1di)ai。则转移方程为:

fj,r+ji=min0rkj+i{fj,r+ji,fi1,r+(dj+1di)ai}

时间复杂度:O(n2k)

参考代码:

int n, l, k;
void solve() {
	cin >> n >> l >> k;
	vector<int>d(n + 2, 0), a(n + 1, 0);
	for (int i = 1; i <= n; ++i) cin >> d[i];
	for (int i = 1; i <= n; ++i) cin >> a[i];
	d[n + 1] = l;
	vector<vector<int>>f(n + 1, vector<int>(k + 1, 0x3f3f3f3f));
	int res = INT_MAX;
	f[0][0] = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = i; j <= n; ++j) {
			int len = j - i;
			for (int r = 0; r + len <= k; ++r) {
				f[j][r + len] = min(f[j][r + len], f[i - 1][r] + (d[j + 1] - d[i]) * a[i]);
			}
		}
	}
	for (int i = 0; i <= k; ++i) res = min(res, f[n][i]);
	cout << res << '\n';
	return;
}
posted @   cherish-lgb  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示