2546
剩余的钱多于5元时, 无论买多贵的东西都可以买成功,那最贵的东西我们一定要买,并且要留在最后买,在那之前应该尽可能地把钱花到5元;
即转化为 背包容量为余额 - 5的01背包问题;
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, m;
while(cin >> n) {
if(n == 0) break;
int a[n];
for(int i = 0; i < n; i ++)
cin >> a[i];
cin >> m;
if(m < 5) cout << m << endl;
else {
int dp[m + 1];
memset(dp, 0, sizeof(dp));
sort(a, a + n);
for(int i = 0; i < n - 1; i ++) //最大价值的物品不参与 肯定会购买它
for(int j = m - 5; j >= a[i]; j --) //总价值-5为背包容量
dp[j] = max(dp[j], dp[j - a[i]] + a[i]);
cout << m - dp[m - 5] - a[n - 1] << endl;}
}
1114
完全背包问题,有一点需要注意,这里需要求的是最小值,则在对dp数组赋初值时应赋 > 其上限的值, 当然dp[0]除外,其值依旧为0;
求最小值的情况下,dp[i]一定刚好占用i个资源;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e9;
struct p {
int val;
int wei;
};
int main() {
int T;
cin >> T;
while(T --) {
int a, b, n;
cin >> a >> b >> n;
int m = b - a;
p f[n];
for(int i = 0; i < n; i ++)
cin >> f[i].val >> f[i].wei;
int dp[m + 1];
for(int i = 1; i <= m; i ++)
dp[i] = maxn;
for(int i = 0; i < n; i ++)
for(int j = f[i].wei; j <= m; j ++)
dp[j] = min(dp[j], dp[j - f[i].wei] + f[i].val);
if(dp[m] == maxn) cout << "This is impossible." << endl;
else cout << "The minimum amount of money in the piggy-bank is " << dp[m] << "." << endl; }
return 0; }

293

被折叠的 条评论
为什么被折叠?



