2020년 3월 8일 시험 반짝이 스파크 절반 + 조합론

.JPG 불멸의 제목

이분법을 만날 수있는 첫 번째 대답은,이 점은 나중에 Entscheidungsproblem되었다.

우리는 지금 생각했습니다 \ (N \ 배 중반 \) , 처음에 가득 형태 (\ 0) \ , 우리가 할 수있는 A의 때마다 \ (m \) 추가의 수 \ (1 \) , 필요한 최종 각 라인은 같을 수 없습니다.

이제 우리는 여전히 두 가지 조건이 위의 사항을 충족해야, 다른 관점에서, 우리는 라인으로 채우기 라인을 고려합니다.

최적 동작의 첫 번째 라인 만 \ (1 \) \ (1 \)가 충전되어, 다음 라인 \ (2 \) \ (1 \) ...

기호가있는 라인 \ (I \) \ (1 \) 의 경우, 총 것이다 \ (C_ {중간} ^ I \) 행의 각 열은 것보다 \ (C_ {중간} ^ { I-1} \)를 \ (1 \) , 조합의 수는 순환 될 수있는.

라인이 열을 참조하는 것만으로는 충분하지 않습니다 경우 측면은 하나가 될 것입니다 최대에, 그것을 만들 수 있습니다 더 \ (\ DisplayStyle \는 \ lceil \ FRAC {RES1 \ 타임즈 I} {MID}을 \ 바로 \ rceil \ 왼쪽) 있는지 확인하기 위해, (\ \ 제작 : 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 << '\n';
	}
	return 0;
}

추천

출처www.cnblogs.com/wljss/p/12663047.html