【题目】
题目描述:
L 的书籍被 M 偷了以后伤心欲绝,决定再购买一些回来,现在有 N 本书可以买,每本书的价格是 a[ i ]元。
现在 L 总共有 M 元,以及 K 张优惠券。 对于每本书,如果使用一张优惠券,则可以用b[i]的优惠价格购买。 注意每本书只能使用一张优惠券,只能购买一次。
L想知道自己最多可以购买几本书?
输入格式:
第一行三个整数 N , K , M
接下来 N 行,每行两个整数,表示 a[ i ] 和 b[ i ]。
输出格式:
一个整数表示答案。
样例数据:
输入
4 1 7
3 2
2 2
8 1
4 3
输出
3
备注:
【解释】
选择第 1、 2、 3 本书,其中第 3 本使用优惠券。总共 5 元。
【数据规模】
对于 20%:N ≤ 10
对于 50%:N ≤ 100
对于另外 20%:K = 0
对于 100%:1 ≤ N ≤ 100000,0 ≤ K ≤ N,M ≤ ,1 ≤ b[ i ] ≤ a[ i ] ≤
【分析】
用一个错解 A 了,数据太水
对于100%数据: 贪心
先使用K张优惠券,买价格最小的。
如果考虑如何扩展当前解 :
1、直接购买一个 a[ i ]
2、退掉一个用优惠券的,用优惠券去买别的 b[ j ] + ( a[ i ] - b[ i ] )
2 种情况看哪一个更优
用堆维护 a[ i ], b[ i ], a[ i ] - b[ i ]
【代码】
大佬的代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include<bits/stdc++.h> #define in read() #define N 100009 #define ll long long using namespace std; inline int read(){ char ch;int res=0; while((ch=getchar())<'0'||ch>'9'); while(ch>='0'&&ch<='9'){ res=(res<<3)+(res<<1)+ch-'0'; ch=getchar(); } return res; } int n,k,a[N],b[N],id[N]; ll m; set<pair<int,int> > s1,s2,s3; bool cmp(int x,int y){return b[x]<b[y];} int main(){ n=in;k=in;scanf("%lld",&m); for(int i=1;i<=n;++i){ a[i]=in;b[i]=in; id[i]=i; } sort(id+1,id+n+1,cmp); if(k==0){//特殊的特判一下 sort(a+1,a+n+1);ll sum=0; for(int i=1;i<=n;++i){ sum+=a[i]; if(sum>m) { printf("%d",i-1); return 0; } } printf("%d",n); return 0; } ll now=0;int ans=0; for(int i=1;i<=k;++i){ now+=b[id[i]];if(now>m) { return printf("%d",ans),0; } ++ans; s1.insert(make_pair(a[id[i]]-b[id[i]],id[i]));//差值 } for(int i=k+1;i<=n;++i){ s2.insert(make_pair(b[id[i]],id[i]));//优惠价 s3.insert(make_pair(a[id[i]],id[i]));//原价 } while(s2.size()){ ll f1=s1.begin()->first+s2.begin()->first,f2=s3.begin()->first; if(f1<f2){ now+=f1;if(now>m) return printf("%d",ans),0; ans++;int u=s2.begin()->second; s1.erase(s1.begin());s2.erase(s2.begin()); s1.insert(make_pair(a[u]-b[u],u));s3.erase(s3.find(make_pair(a[u],u))); } else{ now+=f2;if(now>m) return printf("%d",ans),0; ans++;int u=s3.begin()->second; s3.erase(s3.begin());s2.erase(s2.find(make_pair(b[u],u))); } } printf("%d",ans); return 0; }
最后
以上就是细心棉花糖最近收集整理的关于【2018/10/01测试T3】【WOJ 4010】购买书籍【题目】【分析】【代码】的全部内容,更多相关【2018/10/01测试T3】【WOJ内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复