P2370 yyy2015c01 的 U 盘 (二分+01背包)

题面

在这里插入图片描述

题解

此题 : 体积不超过S,价值不小于P的情况下选取的物品的最大的体积最小(先输 入大小,后输入价值)
01 背包 :在体积不超过v的情况下选取物品的价值最大

对于题中有最大的最小值,我们一般采用的是二分,我们发现,选取接口的大小具有单调性,那么我们就可以二分接口的大小,然后判断体积小于等于此接口下选择的物品是否可以满足要求

整体思路 :将体积排序,二分体积,然后做一遍01背包看是否满足条件,注意清空 f 数组

代码

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
const int N = 1e3 + 10;

ll n, p, s;
PLL a[N];
ll f[N];

bool check(ll x) {
    
    
    memset(f, 0, sizeof(f));
    for (ll i = 1; i <= n; i++)
        if (a[i].first <= x)
            for (ll j = s; j >= a[i].first; j--)
                f[j] = max(f[j], f[j - a[i].first] + a[i].second);
    if (f[s] < p) return false;
    return true;
}

int main() {
    
    
    cin >> n >> p >> s;
    for (ll i = 1; i <= n; i++) {
    
    
        cin >> a[i].first >> a[i].second;
    }
    //将体积从小到大排序
    sort(a + 1, a + 1 + n);
    ll l = a[1].first, r = a[n].first;
    ll res = -1;
    while (l < r) {
    
    
        ll mid = (l + r) >> 1;
        if (check(mid)) {
    
    
            r = mid;
            res = mid;
        } else {
    
    
            l = mid + 1;
        }
    }
    if (res != -1) {
    
    
        printf("%d\n", res);
    } else {
    
    
        printf("No Solution!\n");
    }


    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/115195819