思路:
先转换为有限制的背包问题,然卡常卡过去
c o d e code code
#include<iostream>
#include<cstdio>
#define re register
using namespace std;
int n, m;
int a[110][110], sum[110][110], p[110][110], f[110][10001], g[10001], s[10001];
int main() {
scanf("%d%d", &n, &m);
for(re int i = 1; i <= n; ++ i) {
scanf("%d", &a[i][0]);
for(re int j = 1; j <= a[i][0]; ++ j)
scanf("%d", &a[i][j]), sum[i][j] = a[i][j] + sum[i][j - 1];
for(re int j = 0; j <= a[i][0]; ++ j) {
p[i][j] = 1e9;
re int q = a[i][0] - j;
for(re int k = 1; k + q - 1 <= a[i][0]; ++ k) {
p[i][j] = min(p[i][j], sum[i][k + q - 1] - sum[i][k - 1]);
}
p[i][j] = sum[i][a[i][0]] - p[i][j];
}
}
for(re int i = 1; i <= n; ++ i) {
for(re int j = 0; j <= a[i][0]; ++ j) {
for(re int k = m; k >= j; -- k) {
if(g[k - j] + p[i][j] > f[j][k]) f[j][k] = g[k - j] + p[i][j];
if(f[j][k] > s[k]) s[k] = f[j][k];
}
}
for(re int k = m; k >= 0; -- k)
g[k] = s[k];
}
printf("%d", g[m]);
return 0;
}