CodeForces 201 E.Thoroughly Bureaucratic Organization(贪心+二分+鸽巢原理)
2018-01-01 20:20
453 查看
Description
有一个1~n的排列,每次询问至多可以询问m个位置的数字,但是只会给出乱序后的这些数字,问最坏情况下最少多少次可以还原整个序列
Input
第一行一整数T表示用例组数,每组用例输入两个整数n,m(1≤T≤1000,1≤n,m≤109)
Output
对于每组用例,输出最坏情况下还原整个序列所需的最少询问次数
Sample Input
5
4 1
4 2
7 3
1 1
42 7
Sample Output
3
2
3
0
11
Solution
如果对于任意k,可以知道k次询问,每次询问至多问m个数字可以还原的最长排列长度为n,那么就可以二分得到答案,把每个数字在这k次询问是否被问到看作一个长度为k的01串,第i次询问了这个数字则第i位是1,否则是0,那么我们要找的是尽可能多的这种串,且串之间两两可区分,且对于所有串的某一位,其1的个数不能超过m,因为一次询问至多询问m个数字,首先不考虑这个限制,那么就是至多用km个1去构造尽可能多的可两两区分的长度为k的01串,那么我们可以贪心的先构造C1k个只含一个1且位置不同的串,然后构造C2k个只含两个1且这两个1位置不完全相同的串,….,以此类推可以得到尽可能多的串,下面证明加入这个限制和不加是一样的,假设i位的1的数量大于,那么由于总数不超过km,所以必然存在一个j位其1的数量小于m,记x为第i位是1且第j位是0的串的个数,y为第i位是0且第j位是1的串的个数,显然x>y,从x中选一个串,交换其在第i位和第j位的值,结果是要么该串变成一个和其他串都可区分的串,要么其和这y个串中某一个相同,由于x>y,由鸽巢原理,必然存在一个串,交换其两位后和这y个串均不相同,那么这个串和其他所有串都可区分,x的数量减一,经过有限次这样的操作,必然可以使得那些使用超过m个1的位消失,故该限制没用
Code
有一个1~n的排列,每次询问至多可以询问m个位置的数字,但是只会给出乱序后的这些数字,问最坏情况下最少多少次可以还原整个序列
Input
第一行一整数T表示用例组数,每组用例输入两个整数n,m(1≤T≤1000,1≤n,m≤109)
Output
对于每组用例,输出最坏情况下还原整个序列所需的最少询问次数
Sample Input
5
4 1
4 2
7 3
1 1
42 7
Sample Output
3
2
3
0
11
Solution
如果对于任意k,可以知道k次询问,每次询问至多问m个数字可以还原的最长排列长度为n,那么就可以二分得到答案,把每个数字在这k次询问是否被问到看作一个长度为k的01串,第i次询问了这个数字则第i位是1,否则是0,那么我们要找的是尽可能多的这种串,且串之间两两可区分,且对于所有串的某一位,其1的个数不能超过m,因为一次询问至多询问m个数字,首先不考虑这个限制,那么就是至多用km个1去构造尽可能多的可两两区分的长度为k的01串,那么我们可以贪心的先构造C1k个只含一个1且位置不同的串,然后构造C2k个只含两个1且这两个1位置不完全相同的串,….,以此类推可以得到尽可能多的串,下面证明加入这个限制和不加是一样的,假设i位的1的数量大于,那么由于总数不超过km,所以必然存在一个j位其1的数量小于m,记x为第i位是1且第j位是0的串的个数,y为第i位是0且第j位是1的串的个数,显然x>y,从x中选一个串,交换其在第i位和第j位的值,结果是要么该串变成一个和其他串都可区分的串,要么其和这y个串中某一个相同,由于x>y,由鸽巢原理,必然存在一个串,交换其两位后和这y个串均不相同,那么这个串和其他所有串都可区分,x的数量减一,经过有限次这样的操作,必然可以使得那些使用超过m个1的位消失,故该限制没用
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; int T,n,m; bool check(int k) { if(n==1)return 1; ll num=(ll)m*k,res=1,C=1; for(int i=1;i<=k;i++) { if(num<i)return 0; if((ll)(k-i+1)*C>=(ll)n*i)C=n; else C=C*(k-i+1)/i; ll temp=min(num/i,C); res+=temp; if(res>=n)return 1; num-=temp*i; } return 0; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int l=0,r=n,mid,ans; while(l<=r) { mid=(l+r)/2; if(check(mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); } return 0; }
相关文章推荐
- Codeforces Round #127 (Div. 1) E. Thoroughly Bureaucratic Organization 二分 数学
- Codeforces 201E Thoroughly Bureaucratic Organization (智商题。。)
- codeforces - 732D Exams 【二分 + 贪心】
- CodeForces - 551C 二分+贪心
- CodeForces 734C Anton and Making Potions 【二分】【贪心】
- codeforces 732D Exams 二分搜索 贪心
- Codeforces 732D [二分 ][贪心]
- CodeForces - 732D Exams(二分+贪心)
- CodeForces 287B 二分贪心
- Codeforces 551C - GukiZ hates Boxes (二分 + 贪心)
- CodeForces 551 C. GukiZ hates Boxes(二分+贪心)
- Codeforces 803D Magazine Ad【二分+贪心】
- Codeforces 732D Exams【贪心+二分】
- CodeForces 377B-Preparing for the Contest(二分+贪心)
- Codeforces 373C:Counting Kangaroos is Fun(二分+贪心)
- Codeforces 363D - Renting Bikes(贪心二分)
- CodeForces - 734C Anton and Making Potions 二分+贪心 思维题
- CodeForces-732D-Exams(二分 模拟 贪心)
- Codeforces 479D Long Jumps(贪心+二分)
- Codeforces 760B Frodo and pillows【贪心+二分】