The Preliminary Contest for ICPC Asia Shenyang 2019 C. Dawn-K’;s water

The Preliminary Contest for ICPC Asia Shenyang 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 nn types of mineral water, and he already knew the price pp and the weight cc (kg) of each type of mineral water. Now Dawn-K wants to know the least money aa he needs to buy no less than mm kilograms of mineral water and the actual weight bb 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(1n103)n (1 \le n \le 10^3)

n(1≤n≤103) – the number of types, and

m(1m104)m (1 \le m \le 10^4)

m(1≤m≤104) – the least kilograms of water he needs to buy. For each set of test cases, the sum of nn does not exceed 5e4.

Then followed n lines with each line two integers

p(1p109)p (1 \le p \le 10^9)

p(1≤p≤109) – the price of this type, and

c(1c104)c (1 \le c \le 10^4)

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 aa and the weight of water Dawn-K will get bb. If this minimum cost corresponds different solution, output the maximum weight he can get.

(The answer a is between 1 and

10910^9

109 , and the answer b is between 1 and

10410^4

104 )

样例输入

1
2
3
4
5
6
7
8
3 3
2 1
3 1
1 1
3 5
2 3
1 2
3 3

样例输出

1
2
3 3
3 6

完全背包模板题~
题意转化:有

nn

n 个无限量供应的商品,价值为

pp

p,重量为

cc

c,要求购买的商品总价值最少且总重量至少为

mm

m,求此时的总价值和总重量~
就在完全背包的模板上稍加改动就行,注意题目限制总重量最多为

1e41e4

1e4,所以在循环里可以直接放上避免超时,AC代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1e9;
const int N=1e4+5;
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        int p[n],c[n],dp[N],ans1=inf,ans2=0;
        for(int i=0;i<n;i++) scanf("%d%d",&p[i],&c[i]);
        fill(dp,dp+N,inf);
        dp[0]=0;
        for(int i=0;i<n;i++){
            for(int j=c[i];j<=1e4;j++){
                dp[j]=min(dp[j],dp[j-c[i]]+p[i]);
                if(j>=m){
                    if(ans1==dp[j]&&j>ans2) ans2=j;
                    else if(ans1>dp[j]) ans1=dp[j],ans2=j;
                }
            }
        }
        printf("%d %d\n",ans1,ans2);
    }
}