题目
-
leetcode.cn/problems/nu…
-
codeforces.com/problemset/…
题意(仅第二题)
- 开始给两个数n,op
- n个双端队列,每个长度为m(1≤n≤100,1≤m≤100)
- 问从中取出op个元素,取出元素总和最大是多少
第二题思路(都是分组背包)
- 第一题题解
- 把每一个deque看成是一个分组,分组中的物品就是deque前缀和后缀的所有可能组合
- 但是这样进行分组背包的时间复杂度是O(nopn2),所以我们需要再提炼一下,长度相同的组合,必然选择值最大的哪一个
- 这样对所有分组先做一次前缀和,维护长度相同的组合,值最大的情况,O(n3)
- 最后用分组背包模板,O(n2∗op)
- 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
for(int i = 1
{
cin >> ed[i]
for(int j = 1
{
cin >> a[i][j]
a[i][j] += a[i][j-1]
}
a[i][ed[i]+1] = a[i][ed[i]]
}
for(int i = 1
{
for(int l = 0
for(int r = l+1
{
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
{
for(int j = m
for(int k = 0
{
int va = val[i][k]
if(j - k >= 0)f[j] = max(f[j-k] + va,f[j])
}
}
}
cout << f[m] << endl
}