2016 ACM/ICPC Asia Regional Qingdao Online hdu 5884 Sort (二分+优先队列)★
2016-09-17 18:54
337 查看
题意:
给定n个序列,以及他们的长度,问在总花费不超过T,每次合并的序列个数不多于k的情况下,k的最小值,合并的代价是合并序列的总长度和。
题解:
二分k,再用优先队列取出前k个小的,模拟下去,不过这样会T。由于ai小于1000,所以可以记录这1000个数出现的次数,将出现的数字压入队列,每次出队的时候判断一下就不T了。不过还有一个问题,比如长度为6的序列,每次取前3个,最后一次只会取最后两个,那么我们显然在一开始取两个会使代价更小。
这里的处理就是在一开始合并k1个,结果赛场敲渣了。。。。然后意淫出在队首补0,使得最后一次仍然取k个,强行A掉。。。。
给定n个序列,以及他们的长度,问在总花费不超过T,每次合并的序列个数不多于k的情况下,k的最小值,合并的代价是合并序列的总长度和。
题解:
二分k,再用优先队列取出前k个小的,模拟下去,不过这样会T。由于ai小于1000,所以可以记录这1000个数出现的次数,将出现的数字压入队列,每次出队的时候判断一下就不T了。不过还有一个问题,比如长度为6的序列,每次取前3个,最后一次只会取最后两个,那么我们显然在一开始取两个会使代价更小。
这里的处理就是在一开始合并k1个,结果赛场敲渣了。。。。然后意淫出在队首补0,使得最后一次仍然取k个,强行A掉。。。。
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <list> #include <queue> #include <map> #include <bitset> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-3 #define maxn 100100 #define MOD 1000000007 struct cmp { bool operator ()(int &a,int &b) { return a > b; } }; int n; long long m; int Num[1010]; int num[1010]; int solve(int x) { int cnt = n; while(cnt >= x) cnt -= x-1; return x - cnt; } int main() { int t,C = 1; scanf("%d",&t); while(t--) { scanf("%d%lld",&n,&m); memset(Num,0,sizeof(Num)); for(int i = 0; i < n; i++) { int x; scanf("%d",&x); Num[x]++; } int l = 1,r = n; while(r - l > 1) { int mid = (l+r) / 2; priority_queue<int,vector<int>,cmp> q; memcpy(num,Num,sizeof(Num)); for(int i = 0; i < 1010; i++) if(num[i]) q.push(i); if(solve(mid) != mid - 1) { if(!num[0]) q.push(0); num[0] += solve(mid); } long long ssum = 0; while(!q.empty()) { int cnt = 0; long long sum = 0; while(cnt < mid && !q.empty()) { if(q.top() > 1000) { sum += q.top(); q.pop(); cnt++; } else { int l = min(num[q.top()],mid-cnt); sum += q.top() * l; num[q.top()] -= l; if(!num[q.top()]) q.pop(); cnt += l; } } if(cnt <= 1) break; if(sum <= 1000) { if(!num[sum]) q.push(sum); num[sum]++; } else q.push(sum); ssum += sum; if(ssum > m) break; } if(ssum <= m) r = mid; else l = mid; } printf("%d\n",r); } return 0; }
相关文章推荐
- HDU 5884 Sort 2016 ACM/ICPC Asia Regional Qingdao Online
- 2016 ACM/ICPC Asia Regional Qingdao Online hdu 5884 Sort (智商+队列)★
- HDU 5884 Sort 2016 ACM/ICPC Asia Regional Qingdao Online 1007
- HDU 5878 I Count Two Three (暴力) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5881 Tea (水题) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5875 Function(二分区间+RMQ)——2016 ACM/ICPC Asia Regional Dalian Online
- HDU 5881 Tea(思维)——2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5883 The Best Path 2016 ACM/ICPC Asia Regional Qingdao Online
- 2016 ACM/ICPC Asia Regional Qingdao Online 1001 I Count Two Three(打表+二分搜索)
- HDU 5883 The Best Path(并查集+欧拉回路 or 欧拉路)——2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5878 I Count Two Three 2016 ACM/ICPC Asia Regional Qingdao Online 1001
- HDU 5882 Balanced Game 2016 ACM/ICPC Asia Regional Qingdao Online 1005
- HDU 5883 The Best Path 2016 ACM/ICPC Asia Regional Qingdao Online 1006d
- HDU 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001)
- HDU 5879 Cure (2016 ACM/ICPC Asia Regional Qingdao Online 1002)
- HDU 5878 -- 丑数打表(2016 ACM/ICPC Asia Regional Qingdao Online)
- HDU 5879 Cure 2016 ACM/ICPC Asia Regional Qingdao Online 1002
- HDU 5889 Barricade 2016 ACM/ICPC Asia Regional Qingdao Online 1011
- hdu 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001)
- HDU 5879 Cure 2016 ACM/ICPC Asia Regional Qingdao Online