①暴搜,递归(70分)
#include<iostream>
#include<algorithm>
using namespace std;
int n, x;
int a[35] = {0};
int res = 1e9;
int dfs(int u, int sum){
if(u == n){ //不可以if(u == n && sum >= x) res = min(res, sum);
if(sum >= x) res = min(res, sum);
}else{
dfs(u + 1, sum);
dfs(u + 1, sum + a[u]);
}
return res;
}
int main(){
cin >> n >> x;
for(int i = 0; i < n; i ++){
cin >> a[i];
}
cout << dfs(0, 0) << endl;
return 0;
}
②用二进制数的每一位表示某本书买或是不买(70分)
#include<iostream>
#include<algorithm>
using namespace std;
int n, x;
int a[35] = {0};
int res = 1e9;
int main(){
cin >> n >> x;
for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 0; i < (1 << n); i ++){
int sum = 0;
for(int j = 0; j < n; j ++){
if((i >> j) & 1 == 1) sum += a[j];
if(sum >= x && sum < res) res = sum;
}
}
cout << res << endl;
return 0;
}
③最优解,01背包(100分)
考查转化模型的能力。设总价格为sum,包邮最低价为x,则此题可转化为总体积为sum-x的01背包问题
朴素
#include<iostream>
using namespace std;
int n, x;
int w[33], v[33];
int f[33][300010];
int main(){
cin >> n >> x;
int sum = 0;
for(int i = 1; i <= n; i ++){
cin >> w[i];
v[i] = w[i];
sum += w[i];
}
int m = sum - x;
for(int i = 1; i <= n; i ++){
for(int j = 0; j <= m; j ++){
f[i][j] = f[i - 1][j];
if(j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
}
}
cout << sum - f[n][m] << endl;
return 0;
}
优化
#include<iostream>
using namespace std;
int n, x;
int w[33];
int f[300010];
int main(){
cin >> n >> x;
int sum = 0;
for(int i = 1; i <= n; i ++){
cin >> w[i];
sum += w[i];
}
int m = sum - x;
for(int i = 1; i <= n; i ++){
for(int j = m; j >= 0; j --){
f[j] = f[j];
if(j >= w[i]) f[j] = max(f[j], f[j - w[i]] + w[i]);
}
}
cout << sum - f[m] << endl;
return 0;
}