[BZOJ] 물문제 1864 삼색 두 갈래 나무.
2649 단어 dp
직관적인 느낌은 비교적 어렵다. 왜냐하면 이전의 나무에 염색한 것이 나를 놀라게 하고 오랫동안 생각했기 때문이다.
먼저 한 걸음 한 걸음 문제를 해결하고, 읽는 것은 하나의 어려움이다. 표현열을 나무로 바꾸는 것을 어떻게 해결할 것인가?
'1S1'이든'2S1S2'이든 모두 왼쪽 나무가 있는 것을 발견했고 샘플을 살펴보면 왼쪽 나무가 처리된 후에야 오른쪽 나무를 처리한다는 것을 알 수 있다.그래서 차례로 나무를 세울 수 있습니다. 두 갈래 나무이기 때문에 ls와rs수로 좌우 아들을 저장하면 됩니다.
그러면 어떻게 녹색으로 염색하는 최대치를 구합니까?DP를 생각하다.한 가지 색깔만 염색하면 되기 때문에, 우리는 이 점이 녹색으로 염색되었는지 주목하면 된다!
상태 dp 정의(u, 0/1):
dp(u,1)는 이 점이 녹색으로 염색되었다는 것을 나타낸다. 그러면 자나무는 반드시 다른 색깔일 것이다. 아들이 어떤 색깔로 염색되었는지 신경 쓸 필요가 없다.그래서 전이 방정식 1:
dp(u,1)= dp(ls ( u),0)+ dp(rs ( u),0)+ 1;
dp(u,0)는 이 점이 녹색으로 염색되지 않았다는 것을 나타낸다. 그러면 나무는 반드시 하나는 녹색으로 염색되고 다른 하나는 다른 색으로 염색된다. 단지 우리는 도대체 어느 것이 어떤 색으로 염색되었는지 모른다.걱정하지 마세요. 왼쪽 아들이 녹색으로 염색되었거나 오른쪽 아들이 녹색으로 염색되었을 때 우리는 이 두 가지 상황에 대해 최소치(또는 최대치(필요에 따라 녹색으로 염색된 최치를 결정)만 취하면 이동 방정식을 얻을 수 있습니다.
dp(ls (u),1)+ dp(rs ( u),0)
dp(u,0) min/max
dp(ls (u),0)+ dp(rs ( u),1)
코드:
/**************************************************************
Problem: 1864
User: jerrywans
Language: C++
Result: Accepted
Time:328 ms
Memory:29028 kb
****************************************************************/
#include
const int N = 500000 + 5 ;
int dp [ N << 2 ] [ 3 ] , ls [ N ] , rs [ N ] ;
int tail = 1 ;
int minx ( int a , int b ) {
return a < b ? a : b ;
}
int maxx ( int a , int b ) {
return a > b ? a : b ;
}
void build ( int x ) {
char c ;
scanf ( "%c" , &c ) ;
if ( c == '0' ) return ;
ls [ x ] = ++ tail ;
build ( ls [ x ] ) ;
if ( c == '2' ) {
rs [ x ] = ++ tail ;
build ( rs [ x ] ) ;
}
}
void dfs ( int u , int opt ) {
if ( !u ) return ;
dfs ( ls [ u ] , opt ) ;
dfs ( rs [ u ] , opt ) ;
dp [ u ] [ 1 ] = dp [ ls [ u ] ] [ 0 ] + dp [ rs [ u ] ] [ 0 ] + 1 ;
if ( opt == 1 )
dp [ u ] [ 0 ] = maxx ( dp [ ls [ u ] ] [ 1 ] + dp [ rs [ u ] ] [ 0 ] , dp [ ls [ u ] ] [ 0 ] + dp [ rs [ u ] ] [ 1 ] ) ;
else
dp [ u ] [ 0 ] = minx ( dp [ ls [ u ] ] [ 1 ] + dp [ rs [ u ] ] [ 0 ] , dp [ ls [ u ] ] [ 0 ] + dp [ rs [ u ] ] [ 1 ] ) ;
}
int main ( ) {
build ( 1 ) ;
dfs ( 1 , 1 ) ;
printf ( "%d " , maxx ( dp [ 1 ] [ 0 ] , dp [ 1 ] [ 1 ] ) ) ;
memset ( dp , 0 , sizeof ( dp ) ) ;
dfs ( 1 , 2 ) ;
printf ( "%d" , minx ( dp [ 1 ] [ 0 ] , dp [ 1 ] [ 1 ] ) ) ;
return 0 ;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.