문제 설명 :
다음과 같은 규칙이 현재 순차 번호 1,2,3, ... N 공에 열을 Yaoan되고, n은 컬럼이있는 가정하자.
(1) 당신은 기둥의 상단에 공을 넣을 수 있습니다.
(2) 동일한 열에있는 인접한 두 공 완전한 사각형의 수의 합이다.
공의 최대 개수는 n 개의 컬럼에 넣을 수를 계산하는 알고리즘을 설계하려고합니다. 예를 들어, 네 개의 열 11 공까지 보유 할 수 있습니다.
<< 프로그래밍 작업 :
주어진 N의 경우, 볼의 최대 값을 산출하는 상기 n 개의 열을 넣을 수있다.
4 <= N <= 55
문제 해결
단일 공 중요하지 않고, 결정이 여러 컬럼에 설치해야하는 볼에 추가 될 때 열 수의 증가를 고려할 때 증가한다.
각 볼이 두 지점들로 분할, 작은 쪽 심지어 번만 큰에서 보장하기 위해 연결되어있는 에지의 개수의 제곱 주위 서로 두 볼이 접속되어있다.
문제는 최소한의 경로 커버리지, 경로의 수는 열 수있다된다.
m 공 열거 된 경로의 수가 될 때 응답은 같은 순회 경로의 출력에서 프로그램, 수 m-1 열보다 더 크다.
시간 초과하지 않기 위해, 우리는 새로운 볼이 작은 대형에서조차 가장자리 이유입니다 될 수 있습니다 경로를 보강에서 한 번 공을 실행 추가 할 수 있습니다.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#INCLUDE <비트 / stdc ++ H.> 사용 스페이스 성병; CONST의 INT의 maxn = 3605 ; INT의 N, m; int로 마주 [maxn, 경기 [maxn, 타이머; 불리언 사각형 [maxn << 1 ]; 벡터 < INT > E [maxn]; 공극 초기화 () { 타이머 = 0 ; memset 함수 (일치, 0 , sizeof 연산자 (경기)); memset 함수 (힘, 0 , 는 sizeof (힘)); } BOOL DFS ( INT U) { 경우 (힘 [U] == 타이머)돌아 거짓 ; 힘 [U] = 타이머; 대 (부호 INT = 1 0 ; 나는 <E [U] 크기는 (); 나는 ++ ) { INT의 V = E [U] [I]; 만약 (! 매치 [V] || DFS (매치 [V])) { 매치 [V] = U; 반환 사실 ; } } 반환 거짓 ; } 공극 GET ( INT U) { 의 printf ( " %의 D ' , U); 힘 [U] = 타이머; 만약 (! 일치 [U +1800 ]) {putchar ( 10 ); 반환 } 얻을 (매치 [U + 1800 ]); } 무효 인쇄 () { ++ 타이머; 위한 ( int로 I = 1 ; m <i가 나는 ++는 ) 경우 (! 힘 [I] = 타이머) 하세요 (I); } INT 의 main () { 위해 ( int로 I = 1 ; 나는 = <* 7200 ; 내가 ++ ) 사각형 [내가 * I = 참 ; scanf와 ( " %의 D ' , N); INTANS = 0 ; 반면 (++의 m)은 { 위해 ( int로 I = 1 ; 나는 <m을, 난 ++ ) 경우 (I + E [m] .push_back (광장 [i가 m을 +]) 1,800 ); ++ 타이머; 경우 (DFS (m)) ANS ++ ; 경우 (m-ANS> N) {의 printf ( " % D \ 없음 " , M- 1 ), 인쇄 () 출구 ( 0 );} } }
, 거기 욕심 방법은 기둥 넣어 넣을 수 있습니다, 또는 새롭게 문을 연에 (정확성 모른다).
공 겉으로는 법의 여러 가지가 있습니다 2 + 2 + 4 + 4 + 6 + 6 + ...