zoukankan      html  css  js  c++  java
  • 2020.3.8考试 火花灿灿 二分+组合数学

    神仙题.jpg

    首先答案满足可二分性,二分后变成了判定性问题。

    我们想想现在有个 (n imes mid) 的表格,初始时全为 (0),每次我们能将一列中 (m) 个数添上 (1),要求最后每一行都不能一样。

    现在我们换一种角度,我们考虑一行一行的填,依然要满足上面那两个条件。

    最优的操作是我们先一行只有 (1)(1) 的填,然后一行 (2)(1) ...

    对于一行有 (i)(1) 的情况,一共会有 (C_{mid}^i) 行,每列会多 (C_{mid}^{i-1})(1) ,这里的组合数是可以递推的。

    如果行不够了,看列方面能不能撑得住,最多的一列会多 (displaystyle left lceil frac{res1 imes i}{mid} ight ceil),看是否 (le res2)

    否则如果列不够了,就一票否决了。

    最后看是否有空行

    #include<iostream>
    #include<cstdio>
    #define int long long
    using namespace std;
    int T, n, m, ans, l, r, mid;
    inline int read()
    {
    	int res = 0; char ch = getchar(); bool XX = false;
    	for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
    	for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
    	return XX ? -res : res;
    }
    int check(int mid)
    {
    	int C1 = mid, C2 = 1, res1 = n - 1, res2 = m;
    	for (int i = 1; i <= mid; ++i)
    	{
    		if (i > 1)
    		{
    			C1 = C1 * (mid - i + 1) / i;
    			C2 = C2 * (mid - i + 1) / (i - 1);
    		}
    		if (res1 < C1)return (res1 * i + mid - 1) / mid <= res2;
    		else if (res2 < C2)return 0;
    		res1 -= C1; res2 -= C2;
    	}
    	return !res1;
    }
    signed main()
    {
    	cin >> T;
    	while (T--)
    	{
    		n = read(); m = read();
    		l = 0; r = n - 1;
    		while (l <= r)
    		{
    			mid = (l + r) >> 1;
    			if (check(mid))ans = mid, r = mid - 1;
    			else l = mid + 1;
    		}
    		cout << ans << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    iOS nsstring 截取字符前后字符串
    iOS 计算时间差
    Android的ProgressBar
    Android:OptionMenu
    eclipse the user operation is waiting for building workspace" to complete
    Android存储之SQLiteDatbase
    Android保存之SharedPreferences
    pkg_utility
    Oracle同义词 synonyms
    xzzx
  • 原文地址:https://www.cnblogs.com/wljss/p/12663047.html
Copyright © 2011-2022 走看看