分组背包

题目

  1. https://leetcode.cn/problems/number-of-ways-to-earn-points/description/?orderBy=most_votes

  2. https://codeforces.com/problemset/problem/148/E

题意(仅第二题)

  • 开始给两个数n,op
  • n个双端队列,每个长度为m(1n1001m100
  • 问从中取出op个元素,取出元素总和最大是多少

第二题思路(都是分组背包)

  • 第一题题解
  • 把每一个deque看成是一个分组,分组中的物品就是deque前缀和后缀的所有可能组合
  • 但是这样进行分组背包的时间复杂度是O(nopn2),所以我们需要再提炼一下,长度相同的组合,必然选择值最大的哪一个
  • 这样对所有分组先做一次前缀和,维护长度相同的组合,值最大的情况O(n3)
  • 最后用分组背包模板,O(n2op)
  • 1e8可过,因为背包过程中操作不多,hhh
  • 不要忘记开LL

代码

const int N = 110,M = 10010;
int f[M];
int ed[N];
int a[N][N];
int val[N][N];

void solve()
{
	int n,m;cin >> n >> m;

	for(int i = 1;i <= n;i ++)
	{
		cin >> ed[i];
		for(int j = 1;j <= ed[i];j ++)
		{
			cin >> a[i][j];
			a[i][j] += a[i][j-1];
		}
		a[i][ed[i]+1] = a[i][ed[i]];
	}

	for(int i = 1;i <= n;i ++)
	{
		for(int l = 0;l <= ed[i];l ++)
			for(int r = l+1;r <= ed[i]+1;r ++)
			{
				int &t = val[i][l + ed[i]+1 - r];
				t = max(t,a[i][l] + a[i][ed[i]+1] - a[i][r-1]);
			}
	}

	for(int i = 1;i <= n;i ++)
	{
		for(int j = m;j >= 1;j --){
			for(int k = 0;k <= ed[i];k ++)
			{
				int va = val[i][k];
				
				if(j - k >= 0)f[j] = max(f[j-k] + va,f[j]);
			}
		}
	}

	cout << f[m] << endl;
}
posted @   俄罗斯刺沙蓬  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
返回顶端
点击右上角即可分享
微信分享提示