[J组模拟赛 #002 T4]分组选数
分组选数
题目大意:#
给 个数,第 个数是 ,属于第 个集合中。对于每个集合,若从中选出若干个数,则价值为这些数的异或和,总共的价值就是所有集合的价值的和。现在最多可以选 个数,问可以获得的最大价值是多少。
数据范围:#
对于 的数据:
解题分析:#
朴素做法:#
假设 为第 个集合中的第 个数。
首先,最质朴的想法就是设 为第 个集合里,前 个数中选择 个数能否凑成 。由于异或运算符是可逆的,所以转移方程就是:
然后再进行一个背包,这里 为前 个集合中选 个数的最大答案:
PS:这里 是任意一个数
正解:#
但很明显,朴素做法时间复杂度是 ,会超时,所以我们不妨观察一下状态。由于异或并不满足最优子结构,所以我们把目光转移到了这个:选择 k 个数
。
在尝试将状态变成 f[i][j][l] 表示第 i 个集合中,前 j 个数异或和为 l 最少要选择多少个数
后,我们发现这是可以计算的:
然后对于第 个集合中选择 个数的异或和,我们不妨把它设为 ,然后很明显:
注意:由于答案一定是最优的,所以只更新 最少要取多少个数
是没有问题的,因为大一点的更新后要用的数量更多反而会不好。
然后 的更新还是没有区别:
然后这道题就做完了,时间复杂度 (大概吧,反正是这个量级的)
AC Code:
# include <bits/stdc++.h>
using namespace std;
# define ll long long
# define lf double
# define int ll
# define GO(i,a,b) for(int i = a; i <= b; i ++)
# define RO(i,b,a) for(int i = b; i >= a; i --)
# define FO(i,u,head,e) for(int i = head[u]; i; i = e[i].next)
# define CI const int
# define pii pair<int,int>
# define F first
# define S second
# define PB(x) push_back(x)
# define mem(a,x) memset(a, x, sizeof a)
CI maxn = 2007;
int n, m;
map <int, vector <int> > p;
int x, y;
int f[3007][3007]; // 一个集合中前 i 个元素异或和为 j 所用的最少个数
int s[3007]; // 用 i 个数最大的异或和
int g[3007][3007]; // 前 i 个集合选 j 个数最大和
signed main(){
cin >> n >> m;
GO (i, 1, n){
scanf("%lld %lld", &x, &y);
p[y].PB(x);
}
GO (i, 0, 3000)
GO (j, 0, 3000)
g[i][j] = -2e18;
g[0][0] = 0;
int ii = 0;
int ans = -2e18;
for (auto i : p){
ii ++;
auto x = (i.S);
GO (j, 0, (int) (x.size()))
GO (k, 0, 3000)
f[j][k] = 2e18, s[k] = 0;
f[0][0] = 0;
GO (j, 1, (int) (x.size()))
GO (k, 0, 2000)
f[j][k] = min <int> (f[j - 1][k ^ x[j - 1]] + 1, f[j - 1][k]);
GO (k, 0, 2000) if (f[(int)(x.size())][k] != 2e18) s[f[(int)(x.size())][k]] = max <int> (s[f[(int)(x.size())][k]], k);
GO (j, 0, 2000)
GO (k, 0, min <int> (j, (int) (x.size())))
g[ii][j] = max <int> (g[ii][j], g[ii - 1][j - k] + s[k]);
}
GO (j, 0, m) ans = max <int> (ans, g[ii][j]);
printf("%lld", ans);
return 0;
}
作者:DE_aemmprty
出处:https://www.cnblogs.com/aemmprty/p/16799173.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库