我是靠谱客的博主 细心棉花糖,这篇文章主要介绍【2018/10/01测试T3】【WOJ 4010】购买书籍【题目】【分析】【代码】,现在分享给大家,希望可以做个参考。

【题目】

题目描述:

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 ≤ 10^{14},1 ≤ b[ i ] ≤ a[ i ] ≤ 10^{9}

 

【分析】

用一个错解 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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部