-
背包问题,可以滚动数组优化
-
其次甚至用set模拟一下状态都可以过,测试样例比较水
#include <bits/stdc++.h>
#define endl '\n'
typedef long long ll;
using namespace std;
void solve() {
int n, x; cin >> n >> x;
vector<set<int>> dp(n+1);
vector<int> money(n+1);
int MIN = 0;
for (int i = 1; i <= n; ++i) {
cin >> money[i];
MIN += money[i];
dp[i].insert(0);
}
sort(money.begin(), money.end());
dp[1].insert(money[1]);
for (int i = 2; i <= n; ++i) {
for (auto j : dp[i-1]) {
dp[i].insert(j);
dp[i].insert(j + money[i]);
}
for (auto j : dp[i]) {
if (j >= x && j < MIN) {
MIN = j;
break;
}
}
}
cout << MIN << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
solve();
return 0;
}
记忆化搜索:
#include <bits/stdc++.h>
#define endl '\n'
typedef long long ll;
using namespace std;
int w[35];
int mem[35][300005];
int dfs(int i, int rest) {
if (i == 0 || rest <= 0) return 0;
if (mem[i][rest]) return mem[i][rest];
if (rest < w[i]) return dfs(i-1, rest);
int yes = dfs(i-1, rest-w[i]) + w[i];
int no = dfs(i-1, rest);
return mem[i][rest] = max(yes, no);
}
void solve() {
int n, x; cin >> n >> x;
int sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> w[i];
sum += w[i];
}
int mx = sum - x;
cout << sum - dfs(n, mx) << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
solve();
return 0;
}
空间优化的dp:
#include <bits/stdc++.h>
#define endl '\n'
typedef long long ll;
using namespace std;
int val[35];
int dp[400005];
void solve() {
int n, x; cin >> n >> x;
int sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> val[i];
sum += val[i];
}
int mx = sum - x;
for (int i = 1; i <= n; ++i) {
for (int j = mx; j >= val[i]; --j) {
dp[j] = max(dp[j-1], dp[j-val[i]] + val[i]);
}
}
cout << sum - dp[mx] << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
solve();
return 0;
}