BZOJ2590: [Usaco2012 Feb]Cow Coupons

n<=50000组数Ai,Bi,Ai>=Bi,最多K<=n个组选Bi,其他组选Ai,求最多能选中几组数使选数总和不超过M<=1e14。

一开始,肯定是在Bi里面选K个最小的,然后M有剩的再来调整。如何调整呢?现在我有两个选择:在没选的数里面选个最小的Aj,否则在选的K个最小Bi的里面,把某个Bi换成Ai,多出一次机会拿没选的数字中最小的一个Bj。前者可以开个堆或排个序,后者其实是要找Ai-Bi+Bj的最小,开两个堆分别维护Ai-Bi的最小和Bj的最小即可。

第一次WA:Bj选中后忘了把Aj-Bj加入堆。第二次WA:最后的printf打在了else外也就是输出了两个答案。

很好。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 #include<queue>
 6 //#include<iostream>
 7 using namespace std;
 8 
 9 int n,K;
10 #define LL long long
11 LL t;
12 #define maxn 50011
13 int a[maxn],b[maxn];bool vis[maxn];
14 struct node
15 {
16     int id;LL v;
17     bool operator < (const node &b) const {return v<b.v;}
18     bool operator > (const node &b) const {return v>b.v;}
19 }tb[maxn];
20 priority_queue<node,vector<node>,greater<node> > qa,qb,qc;
21 int main()
22 {
23     scanf("%d%d%lld",&n,&K,&t);
24     for (int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]),tb[tb[i].id=i].v=b[i];
25     sort(tb+1,tb+1+n);
26     memset(vis,0,sizeof(vis));
27     int ans=0;
28     for (int i=1;i<=K;i++)
29     {
30         t-=tb[i].v;
31         if (t<0) break;
32         vis[tb[i].id]=1;
33         ans++;
34     }
35     if (t<0) printf("%d\n",ans);
36     else
37     {
38         for (int i=1;i<=n;i++)
39             if (vis[i]) qc.push((node){i,a[i]-b[i]});
40             else qa.push((node){i,a[i]}),qb.push((node){i,b[i]});
41         while (t>=0)
42         {
43             while (!qa.empty() && vis[qa.top().id]) qa.pop();
44             while (!qb.empty() && vis[qb.top().id]) qb.pop();
45             if (qa.empty() || qb.empty()) break;
46             int tmp=qb.top().v+qc.top().v;
47             if (tmp<qa.top().v)
48             {
49                 t-=tmp;
50                 if (t<0) break;
51                 ans++;
52                 vis[qb.top().id]=1;
53                 qc.pop();
54                 qc.push((node){qb.top().id,a[qb.top().id]-b[qb.top().id]});
55                 qb.pop();
56             }
57             else
58             {
59                 t-=qa.top().v;
60                 if (t<0) break;
61                 ans++;
62                 vis[qa.top().id]=1;
63                 qa.pop();
64             }
65         }
66         printf("%d\n",ans);
67     }
68     return 0;
69 }
View Code

 

posted @ 2017-09-19 21:41  Blue233333  阅读(307)  评论(0编辑  收藏  举报