背包 —— HDU2546 && 1114

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; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值