USACO 2016 US Open [262144 게임]

1993 단어 usaco동적 기획
Description
Bessie는 핸드폰에서 게임을 다운받아 노는 것을 좋아하지만 발굽이 너무 커서 작은 핸드폰 화면에서 조작하기 어렵다.
그녀는 최근에 한 게임에 푹 빠졌다. 게임은 처음에 n개의 정수(2<=n<=262144)가 있고 범위는 1-40이다.각 단계에서 베시는 서로 인접한 두 개의 같은 수를 선택한 다음에 원래보다 큰 수(예를 들어 두 개의 7을 하나의 8로 합친 것)를 합쳐서 합칠 수 없다. 게임이 끝날 때까지 목표는 마지막 최대의 수를 최대화하는 것이다. Bessie를 도와 최대치를 구하자.
Input Format
입력 형식: (262144.in)
첫 번째 줄 n, 그리고 n 줄은 각각 게임을 시작할 때의 개수이다.
Output Format
출력 형식: (262144.out)
Bessie가 생성할 수 있는 최대 수
Sample Input
4
1
1
1
2

Sample Output
3

Hint
샘플 해석
두 번째와 세 번째 1을 2로 합친 다음 두 개의 2를 3으로 합친다.
절차:
1 1 1 2
1 2 2
1 3
[문제풀이]
한 문제 문제가 물이 아니라 데이터가 매우 물이 많은 동귀제.
개인적으로 이 문제는 배가된 전기예처리(f[i][j]=f[f[i][j-1][j-1]][j-1])와 유사하다고 생각한다.(왜 많은 사람들이 합병류동귀처럼 생각하는지 모르겠다)
곰곰이 생각해 보면 본 문제의 한 구간 내의 수가 반드시 완전히 합쳐질 수 있는 것은 아니기 때문에 상태표에 합성 수치를 기록하거나 구간 범위는 취할 수 없는 것이다
따라서 상태 설계를 할 때 한 구간 내의 모든 수를 병합하도록 강요해야 한다. 데이터 범위를 보면 구간의 두 단점을 모두 상태 안에 표시하는 것도 바람직하지 않다(메모리가 폭발한다)
그 후에 한 구간의 완전 합병 숫자가 확정된 것을 발견했다. 그래서 한 단점이 합병된 값을 알고 다른 단점도 확정했다. 마침 숫자가 매우 작기 때문에 (많으면 58) 상태에서 한 단점과 합성된 수치를 표시했다. 그러면 상태는 233(f[j][i])로 설계되었다. 이것은 j수를 왼쪽 단점 수치로 i로 할 때 오른쪽 단점의 위치를 나타낸다.
그래서 배증과 매우 비슷한 전이 방정식 f[j][i]=f[f[j][i-1]+1][i-1]이 생겼다. 그리고 프로그램은 초기값을 f[i][a[i]]=i라고 잘 썼다.
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int i,j,k,l,m,n;
int f[262200][65],a[262200];
int main()
  {
  	scanf("%d",&n);
  	for (i=1;i<=n;i++) scanf("%d",&a[i]),f[i][a[i]]=i,m=max(m,a[i]);
  	for (i=1;i<=m;i++)
  	  {
  	  	for (j=1;j<=n;j++)
  	  	  if (f[j][i]!=0&&f[f[j][i]+1][i]!=0) 
  	  	    {
				f[j][i+1]=f[f[j][i]+1][i];
				if (i+1>m) m=i+1;
		    }
	  }
	printf("%d",m);
  }

좋은 웹페이지 즐겨찾기