问题描述
Dawn-K最近在东北大学超市发现了一个非常神奇的现象:大包装并不一定比小包装贵这一天,黎明来到超市买矿泉水,他发现有n种矿泉水,他已经知道每种矿泉水的价格p和重量c (kg)。现在,Dawn-K想知道a买不少于m公斤矿泉水最少需要多少钱,以及他能得到的实际重量b。请帮他计算一下。
输入
输入由多个测试用例组成,每个测试用例以一个数字n (1<=n <=103)开始——类型的数量,以及m (1<=m<=104)——他需要购买的最少公斤水。对于每一组测试用例,n的和不超过5e4。然后沿着n行,每一行两个整数p (1<=p<=109)——这种类型的价格,c(1<=c<= 104)——这种水的重量。输出对于每个测试用例,应该输出一条包含最小代价a的直线,water Dawn-K的权值为b。如果这个最小代价对应不同的解,则输出他能得到的最大权值。(答案a在1和109之间,答案b在1和104之间
输出
对于每个测试用例,应该输出一条包含最小代价a的直线,water Dawn-K的权值为b。如果这个最小代价对应不同的解,则输出他能得到的最大权值。(答案a在1和109之间,答案b在1和104之间
样例输入
3 3
2 1
3 1
1 1
3 5
2 3
1 2
3 3
样例输出
3 3
3 6
分析:
d[i]表示恰好买i公斤的最小花费
背包范围两倍最大m,2e4
赛中傻逼了
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e4+5;
int p[maxm],c[maxm];
int d[maxm];
signed main(){
int n,m;
while(cin>>n>>m){
for(int i=1;i<=n;i++){
cin>>p[i]>>c[i];
}
for(int i=1;i<maxm;i++){
d[i]=1e18;
}
d[0]=0;
for(int i=1;i<=n;i++){
for(int j=c[i];j<maxm;j++){
d[j]=min(d[j],d[j-c[i]]+p[i]);
}
}
int v=1e18,w=0;
for(int i=m;i<maxm;i++){
if(d[i]<=v){
v=d[i];
w=i;
}
}
cout<<v<<' '<<w<<endl;
}
return 0;
}