HDU 5884 Sort(二分+优先队列)

http://acm.hdu.edu.cn/showproblem.php?pid=5884

题意:
有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和。现在另外一个屌丝要他最后合并成一个数组时的总代价不能超过T。求k的最小值。

思路:
贪心策略是长度越小的肯定先进行合并。一开始是直接用一个优先队列,但是这样会TLE的。。

后来改成了用两个队列进行模拟,先将数组排好序然后放入队列之中,每次合并之后的放入另一个队列之中,每次只需要再两个队列之中选择小的即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 #include<bitset>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn=100000+5;
17 
18 ll n,t;
19 int a[maxn];
20 
21 bool solve(int x)
22 {
23     queue<ll> q1,q2;
24     int left=(n-1)%(x-1);
25     if(left) for(int i=1;i<=x-1-left;i++)  q1.push(0);
26     for(int i=1;i<=n;i++)  q1.push(a[i]);
27     ll sum=0;
28 
29     while(!q1.empty() || !q2.empty())
30     {
31         int tmp=0;
32         for(int i=1;i<=x;i++)
33         {
34             if(q1.empty())
35             {
36                 tmp+=q2.front();
37                 q2.pop();
38             }
39             else if(q2.empty())
40             {
41                 tmp+=q1.front();
42                 q1.pop();
43             }
44             else
45             {
46                 int u=q1.front();
47                 int v=q2.front();
48                 if(u<v)
49                 {
50                     tmp+=u;
51                     q1.pop();
52                 }
53                 else
54                 {
55                     tmp+=v;
56                     q2.pop();
57                 }
58             }
59         }
60         sum+=tmp;
61         if(!q1.empty() || !q2.empty())  q2.push(tmp);
62     }
63     return sum<=t;
64 }
65 
66 int main()
67 {
68     //freopen("in.txt","r",stdin);
69     int T;
70     scanf("%d",&T);
71     while(T--)
72     {
73         scanf("%lld%lld",&n,&t);
74         for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
75         sort(a+1,a+n+1);
76         int ans=1;
77         int l=2,r=n;
78         while(l<=r)
79         {
80             int mid=(l+r)/2;
81             if(solve(mid)) {ans=mid;r=mid-1;}
82             else l=mid+1;
83         }
84         printf("%d
",ans);
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7484289.html