题目链接:http://codeforces.com/contest/1077/problem/D
题意:给你一个长度为n的序列,选出从中选出一个长度 t 的子序列s,每次从序列中删去s序列中的数字。求能删最多次的序列t。
n 范围 2e6
题解:
先解释一波样例。
7 3
1 2 3 2 4 3 1
原序列长度为7,要求序列长度为3
为了使删的次数最多我们选择1 2 3 这样能删2次。
题解:桶排序来求一下各个数字的次数,二分能删的次数。然后判断是否能从原序列取出这多次的各个数字。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 +10;
int n,k;
int cnt[N]; // cnt【i】表示
vector<int> ans; // 结果数组
bool judge(int x){ // 每次尝试取出k个数字
ans.clear();
int kk = k;
for(int i = 1 ; i < N ; i ++){
int nums = min(cnt[i]/x,kk);
kk -= nums;
for(int j = 0 ; j < nums ; j ++)
ans.push_back(i);
cout << kk << endl;
}
if(kk == 0) return true;
else return false;
}
int main(){
scanf("%d%d",&n,&k);
int tmp ;
for(int i = 1 ; i <= n ; i ++){
scanf("%d",&tmp);
cnt[tmp] ++;
}
int l = 1;
int r = n;
while(l < r - 1 ){
int mid = (l+r) >> 1;
// cout << mid << endl;
if(judge(mid)) l = mid;
else r = mid;
}
if(!judge(r)) judge(l);
for(auto val : ans){
printf("%d ",val);
}
printf("\n");
}