分组背包
...大约 1 分钟
题目
题意(仅第二题)
- 开始给两个数n,op
- n个双端队列,每个长度为m()
- 问从中取出op个元素,取出元素总和最大是多少
第二题思路(都是分组背包)
- 第一题题解
- 把每一个deque看成是一个分组,分组中的物品就是deque前缀和后缀的所有可能组合
- 但是这样进行分组背包的时间复杂度是O(nop),所以我们需要再提炼一下,长度相同的组合,必然选择值最大的哪一个
- 这样对所有分组先做一次前缀和,维护长度相同的组合,值最大的情况,
- 最后用分组背包模板,
- 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;
}
Powered by Waline v2.15.5