Solution
转移方程比较简单,这里就直接给出了。代表第
首歌结束的时候是
的音量,并且可以满足前面
首歌都不低于0和不大于
的条件。
初始条件就是。
转移方程就是下面给出的,注意不要越界了。
状态总数,转移时间复杂度
,空间复杂度
。
解决之后考虑如何做下优化吧,第一步首先知道对于第个物品可以更新的状态只有
,使用滚动数组压缩空间,可以压缩到空间复杂度是
。
第二个优化就是卡常大师
,把枚举状态的过程进行加速,最终优化出来的代码就是下面的样子了,这样可以把数据出的更大很多。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 50 + 7;
const int M = 1e3 + 7;
int n, m, maxi;
bitset<M> f[2], p;
int a[N];
int op = 0;
int main() {
cin >> n >> m >> maxi;
for (int i = 0; i <= maxi; ++i)
p[i] = 1; // 保证大于maxi的都变成0
for (int i = 1; i <= n; ++i)
cin >> a[i];
f[0][m] = 1;
for (int i = 1; i <= n; ++i) {
op ^= 1;
f[op].reset();
f[op] |= (f[op ^ 1] >> a[i]);
f[op] |= (f[op ^ 1] << a[i]) & p;
}
for (int i = maxi; ~i; --i)
if (f[op][i]) {
cout << i << endl;
return;
}
cout << -1 << endl;
return 0;
} 
京公网安备 11010502036488号