1. 程式人生 > >HDU 5884 Sort(二分+優先隊列)

HDU 5884 Sort(二分+優先隊列)

兩個 col 排好序 一個隊列 sca 超過 開始 -- sum

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\n",ans); 85 } 86 return 0; 87 }

HDU 5884 Sort(二分+優先隊列)