#include <stdio.h>
#include <memory.h>
#define mod 1000000
int cache[ 101 ][ 101 ][ 2 ];
template< int order >
int solve( int lo, int hi )
{
if( !lo && !hi )
return 1;
int& ret = cache[ lo ][ hi ][ order ];
if( ret == -1 )
{
ret = 0;
const int end = order ? hi : lo;
const int dir = order ? +1 : -1;
lo -= !order;
hi -= order;
for( int i = 0; i < end; ++i )
ret = ( ret + solve< !order >( lo + i * dir, hi + i * -dir ) ) % mod;
}
return ret;
}
int main()
{
int n;
scanf( "%d", &n );
int ans = n;
memset( cache, -1, sizeof cache );
if( n > 2 )
{
ans = 0;
const int m = n - 1;
for( int y = 1; y <= n; ++y )
for( int x = 1; x <= n; ++x )
if( y < x )
ans = ( ans + solve< 0 >( x - 2, n - x ) ) % mod;
else if( y > x )
ans = ( ans + solve< 1 >( x - 1, m - x ) ) % mod;
}
printf( "%d ", ans );
return 0;
}
뭐 트릭 좀 더 부리면 확 줄일 수 있겠는데 급귀찮아졌다.
크.. 두개의식을 tensor형태로 합치신것 같습니다.
상수 조건은 최적화 되니까, 컴파일러 최적화 제대로 걸리면 오버헤드는 없엉
ret!=-1 안에 수식은 전부 넣은것도 사실 최적화를 생각하면 옮은 것이겠죠
ㅇㅇ
저 양방향 루프 군살 없게 다 계산할 수 있지만 귀찮아서 = _ = 다시 안쓸 코드에 공들이기 싫어졌다. ㅋㅋ
저한태는 좀 새로운 문법이 templete 사용같은데 이런식으로 사용하는걸 뭐라고 해야되는거죠?? 제가 템플릿 훍어볼때 이렇게 쓰는 경우는 못봤는데
아 그리고 이땐 cash 가 아니라 cache 야 유의.
양방향 루프라고 하시면 어떤거 말씀이신지 ... 음?
응? 그냥 함수 템플릿이지~ 제네릭 프로그래밍이구~
저러면 실제론 함수가 두 개 생성되지. 컴파일 타임에 0 짜리랑 1 짜리랑.
아 그렇군요. 함수에서 order을 사용했으니 <order>을 제외하고 함수를 부르면 호출이 안되겠죠?
하나 또 궁금한게 bool order가 아니라 int order로 선언하셨는지 궁금합니다
응 저걸 넣어줘야 함수가 완성돼.
저거 자체론 함수가 아니거든, 템플릿 인자가 모두 채워져야 함수가 되는것.
상관없잖아. 어차피 배열 인덱스에 사용될때는 정수취급이니.
고수의 코드를 보고 배워갑니다. 기존의 제 코드스타일에서 몇군데 멜팅이 일어나네요 ㅎㅎ 감사합니다.
템플릿의 사용 방식, ret!=-1을 버리지말고 최적화, 상수를 통한 일반화, 어김없이 사용하시는 멤셋, 분기의 최소화, 최종적 심플함
약간 수정함~
8byte을 아끼는 절약정신까지 캬 ;
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
그냥 코드가 너무 복잡해보여서
시각적 테러를 줄임요 ㅋㅋ
ㅋㅋㅋㅋ 근데 갑자기 드는 생각은 int 두개를 줄이면 주소를 가르키는 메모리 8바이트 실제 저장 메모리 8바이트 해서 실제로는 16바이트 절약이겠죠? 그리고 이 변수가 어떤 형의 변수라는 정보는 컴파일러가 처리해야될탠데 그에대한 메모리값또한 지출이 있을거 같아요.
ㅋㅋ 컴파일타임의 소모는 어차피 런타임에 상관없으니 무시해도 됨. 상수를 만들었던걸 변수 수정으로 옮긴것 뿐 : )
대신 저렇게 하면 조건분기 처럼 보이지 않으니 눈이 편하지.
그리고 저런처리는 메모리 사용량에 상관있는게 아니라 레지스터 회피랑 감소 연산으로 이어지기 때문에 사실 같다고 보면돼.
컴파일속도는 저쪽이 쥐똥만큼 빨라지지. 실제 의미에 가까우니.
그렇군요. 레지스터 회피가 일어나는군요... 컴파일러 공부를 해볼까라는 생각이 드네요.
정말 최적화된 코드를 만들고 싶다고 생각할때 필요한건 컴파일러같아요
ㅋㅋ 그건 컴파일러 공부가 아니라 어셈블리 공부를 해야됨.
그리고 제 코드 같은경우는 if로 order을 한번만 호출하는데 여기서 4번 호출하고 ? : 연산이 if보다는 빠르다고 하지만 2번 호출하니까 인간이 보기엔 편하지만 살짝 더 느린게 아닌지 생각듭니다.
상수 조건은 최적화 된다니깐 ㅋㅋ 0 으로 만들어진 함수에선 0측 1로 만들어진 함수에선 1측만 코드로 남겨
쟤는 순수상수잖아. 리터럴로 박혀 있는.
아 어셈블을 공부하면 확실히 알수 있겠네요 ㄷㄷ ;; 근데 어셈블은 악명이 높아서 너무 무섭다능 ...
그니까 저기 order 에 사용한 모든 조건문은 컴파일타임 조건문이지 런타임 코드엔 조건문으로 남아있지 않음.
그래서 니꺼보다 빨라~ 훨~
첫째, 루프 안에서 -1 없앴지.
둘째, 재귀함수의 인자를 하나 줄였지.
셋째, order 에 대한 분기를 없앴음
다만 디버깅 모드에선 상수 조건도 최적화 안하고 처리해버려서 좀 더 느릴순 있음유~
넵 ㅋㅋ 실행속도 물어본껀 3번부분 한정이었습니다. 저런식으로 작성하면 조건문이 지워지고 방식으로 런타임코드가 작성 되는군요.
상수 조건 최적화는 정확하게 어떻게 구현되는지는 100%는 모르겠지만 80%정도 감은 조금 오네요. ㅎㅎ
응 니가 ( 1 + 3 ) 이런걸 쓰면 당연히 컴파일러가 최적화 하겠지?
!order 도 똑같이 리터럴 상수 니까 컴파일러가 최적화 하겠지?
order ? 도 리터럴 조건문이니 컴파일러가 최적화 하겠지?
다 날아가고 없는거.
넵
아 그렇군요
ㅇㅎ ㅇㅎ
니라 if ( 0 ) { .......... } 를 짜면 중괄호 안의 코드가 안남아 있겠지?
그런거지.
니가.
혼자서는 고민해도 결론내리지 못했을 의문을 무릅을 탁치고 갑니다 ㅋㅋ
ㅋㅋㅋㅋㅋ
그러니 아마 한 15% 는 빨라졌을걸?
ㅋㅋ 결국 첫번째 의문과 두번째 의문은 같은 것이었군요
상수 최적화를 통해서 조건문 제거!
이제 상수 조건 기각에 대해 완전히 이해하셨군유. 축하드립니다.
감사합니다. 흐흐 아침부터 보물창고 털었네요.
ㅋㅋㅋ 기분 좋게 하루를 시작합시당~
넵 코세님도 좋은주말 보내시길!