2019瀋陽網絡賽(C)Dawn-K's water完全揹包

Dawn-K recently discovered a very magical phenomenon in the supermarket of Northeastern University: The large package is not necessarily more expensive than the small package.

On this day, Dawn-K came to the supermarket to buy mineral water, he found that there are n types of mineral water, and he already knew the price p and the weight c (kg) of each type of mineral water. Now Dawn-K wants to know the least money a he needs to buy no less than m kilograms of mineral water and the actual weight b of mineral water he will get. Please help him to calculate them.

Input

The input consists of multiple test cases, each test case starts with a number n (1≤n≤103) – the number of types, and mm (1≤m≤10^4) – the least kilograms of water he needs to buy. For each set of test cases, the sum of n does not exceed 5e4.

Then followed n lines with each line two integers p (1≤p≤109) – the price of this type, and c (1≤c≤104) – the weight of water this type contains.

Output

For each test case, you should output one line contains the minimum cost a and the weight of water Dawn-K will get b. If this minimum cost corresponds different solution, output the maximum weight he can get.

(The answer a is between 1 and 10^9, and the answer b is between 1 and 10^4

樣例輸入複製

3 3
2 1
3 1
1 1
3 5
2 3
1 2
3 3

樣例輸出複製

3 3
3 6

鏈接:

https://nanti.jisuanke.com/t/41401

題意:

有n種礦泉水,給出你每種礦泉水的價格和水量,現在給你一個m,讓你求水量不少於m所花的最小价值,如果最小价值相同,則輸出他可以獲得的最大重量。每種水可以買多次。

解析:

完全揹包模型。

我們可以dp[i]表示水量爲i時花費的最小价值。

利用完全揹包模型即可。因爲求的最小值,初始值應爲INF,邊界dp[0] = 0;

因爲答案的範圍爲1-10000,我們可以從m遍歷到10000,找最小的價值。如果相同,取後面遍歷到的。

代碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000+20;
const int INF = 0x3f3f3f3f;
int p[maxn], v[maxn];
int dp[10000+50];
int main()
{
    int n, m;
    while(scanf("%d %d", &n, &m)!=EOF) {
        for(int i = 1; i <= n; i++) {
            scanf("%d %d", &p[i], &v[i]);
        }
        memset(dp, INF, sizeof(dp));
        dp[0] = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = v[i]; j <= 10000; j++) {
                dp[j] = min(dp[j], dp[j-v[i]] + p[i]);
            }
        }

        int maxx = dp[m];
        int ans = m;
        for(int i = m; i <= 10000; i++) {
            if(dp[i] <= maxx) {
                maxx = dp[i];
                ans = i;
            }
        }
        printf("%d %d\n",maxx, ans);
     
    }


    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章