신속한 애플리케이션 매트릭스 전원 동작 문제 재발을 해결할 수있다. 실제로, 피사체가 직접 재귀주고 조심스럽게 신속하게 문제 해결을 가속화 문제를 분석하고 재귀 확인하고 매트릭스 전원 작업을 사용하지 않아도 때때로이다.
[실시 예 1] 프로그램 독해.
다음 C 언어 프로그램 :
#INCLUDE <STDIO.H>
INT의 main ()
{
INT의 N, M, F, I;
반면 (는 scanf ( "% d 개 %의 D", 및 N, m) = EOF!)
{
F = 0;
대 (I = 1; i가 <= N; 내가 ++)
{
경우 (I & 1) = F (f를 * 2 + 1) %의 m;
또 F = F * 2 % m;
}
의 printf ( "% D \ 없음 ', F);
}
0을 반환;
}
입력에 따라 상기 과정, m 및 n은 읽기는 프로그램의 실행 결과를 작성한다. 예컨대, 입력 (310), 출력은 5가 될 것이다.
그러나, n 및 m의 데이터 영역에 입력 한 주어진다 <= N, m <= 1,000,000,000는 시험 세트에서 많은 양의 데이터를 직접 전송하는 소정의 프로그램이 타임 아웃 경우되도록. 사용자는 n 개의 입력에 따라 프로그램을 작성하고 신속 주어진 프로그램의 기능을 달성하기 위해, 문제를 해결하고있어.
(1) 아이디어를 프로그래밍.
감안 블록 실제로 반복적 인 방식으로 (N) %의 m f를 평가한다. 나머지 계산의 F (n)의 방법을 찾을 것으로 간주된다.
주어진 공지 프로그램, F (0) = 0, n이 홀수이고, F (N) = 2 × (F)의 분석 (N-1) +1] N이 짝수 (N) F = 2 * F는 (때 N-1).
다음 추가 분석은 통합 재귀의 n 개의 패리티를 고려하지 발견.
n이 홀수 일 때, F (N) = 2 * F는 (N-1) + 1, N-1은 짝수, F (N-1) = 2 * F (N-2)이어야한다. 따라서,
F (N) = F (N-1) + F (N-1) + 1 = 2 * F (N-2) + F (N-1) +1.
N은 N-1 항상 홀수 F (N-1) = 2 * F (N-2) +1 짝수 (N) F = 2 * F (N-1) 인 경우. 따라서,
F (N) = F (N-1) + F (N-1) = 2 * F (N-2) + F (N-1) +1.
따라서, 균일 한 재귀 식을 얻는다 : F (0) = 0, F (1) = 1, (n)은 F = 2 * F (N-2) + F를 (N-1) +1 (N> = 3).
재발 수식을 결정한 후, 행렬 P는 빠르게 지수를 해결하기 위해 구성 될 수있다.
(2) 소스.
#INCLUDE <STDIO.H>
사용법 #include <string.h>
구조체 매트릭스
{
__int64 매트 [4] [4]; //存储矩阵中各元素
};
매트릭스 matMul (a, 접속 행렬 b, INT의 N, INT가 매트릭스의 m)
{
매트릭스 C;
memset 함수 (c.mat, 0는 sizeof (c.mat));
int로 I, J, K;
경우 (K = 1; K <= N; ++ K)
에 대해 (ⅰ ++는 I = 1; 나는 <= N)
경우 (! a.mat [I] [K] = 0)
J <=; (j = 1 N, J ++)
c.mat [I] [J] = (c.mat [I] [J] + a.mat [I] [K] * b.mat [K] [J]) %의 m;
C를 반환;
}
매트릭스 quickMatPow (a, INT의 N, INT의 B, INT의 m을가 매트릭스) // N阶矩阵快速B 형次幂
{
매트릭스 C;
memset 함수 (c.mat, 0는 sizeof (c.mat));
I 값 int;
대 (I = 1; i가 <= N; 내가 ++)
c.mat [I] [I] = 1;
반면 (b! = 0)
{
경우 (B & 1)
C = matMul (C, A, N, m); // C = C *는;
A = matMul (A, A, N, m); // A = A *
B / 2 =;
}
C를 반환;
}
INT의 main ()
{
INT의 N, m;
__int64 ANS;
행렬 P;
반면 (는 scanf ( "% d 개 %의 D", 및 N, m) = EOF!)
{
memset 함수 (p.mat, 0는 sizeof (p.mat));
p.mat [2] [1] = 2;
p.mat [1] [2] = p.mat [2] [2] = 1;
p.mat [2] [3] = p.mat [3] [3] = 1;
(N <3)의 경우
의 printf ( "% D \ 없음", N %의 m);
또
{
p = quickMatPow (p, 3, N-2, m);
세 p.mat = [2] [1] %의 m;
연간 = (+ p.mat 년 [2] [2] * 2) %의 m;
연간 = (+ p.mat 년 [2] [3]) %의 m;
의 printf ( "% I64d \ n을", 년);
}
}
0을 반환;
}
[실시 예 2] 오프 모든 조명.
초기 완전 점등 일렬로 배열 램프 제 램프 프레스 (가압 후의 상태를 변경)을 N있다. 모든 조명 오프 제 K 및 K + 1 번째 조명하면, K + 2 등의 프레스 일 수있다. 적어도 모든 조명을 근절하는 방법을 많은 단계 물어?
예를 들어, N = 2, 2 호를 필요로한다. 처음 두 조명 호 제 등을 없애기, 호를 없앤다. 경우 N = 3, 5 호해야한다. 호 호는 (2, 직접 조명 오프 소등 주 1 수없는 등) (3), (3 개) 1 호 등을 조명 없애기 제 등 및 제 등의 제 2 번 호 없애기 없애기 빛, 5 개 호 없애기 조명.
(1) 아이디어를 프로그래밍.
F [N]을 설정하고 N 전체 밝은 빛도 전체 램프 점등에 필요한 단계의 최소 개수 소멸하게 나타낼 수있다 오프 전체 전체 N에 필요한 최소 수의 단계가된다 나타낸다.
1), 최종 램프를 없애기 위하여는 N-2 (제 n-1 조명에있어), N-2] +1 F 여러 단계를 필요로 프론트 라이트를 없애기한다.
2) N-1 등을 없애기 위해서, N-2, N-2 백라이트 램프에 조명 램프 번째 백 있도록해야 다시 N-3 등의 수 있도록있다. .. N-2해야, 즉 빛을 다시 턴온되기 전에, F 필요한 단계의 수 [N-2].
3) 앞 N-2 백라이트 램프 후, N-1 등을 떠나기 전에, 즉은, 남은 작업은 N-1 등 외출 넣어 밝은된다 N- [F 필요한 공정 수가 1].
요약하면 : F [N] = 2 * F [N-2] + F [N-1] + 1. (N> = 3) F [ 1] = 1, F [2] = 2.
(2) 소스.
#INCLUDE <STDIO.H>
사용법 #include <string.h>
#DEFINE MOD 200907
구조체 매트릭스
{
__int64 매트 [4] [4]; //存储矩阵中各元素
};
매트릭스 matMul (a, 접속 행렬 b, INT가 매트릭스 않음)
{
매트릭스 C;
memset 함수 (c.mat, 0는 sizeof (c.mat));
int로 I, J, K;
경우 (K = 1; K <= N; ++ K)
에 대해 (ⅰ ++는 I = 1; 나는 <= N)
경우 (! a.mat [I] [K] = 0)
J <=; (j = 1 N, J ++)
c.mat [I] [J] = (c.mat [I] [J] + a.mat [I] [K] * b.mat [K] [J]) % MOD;
C를 반환;
}
매트릭스 quickMatPow (INT의 B, N int로하는을가 매트릭스) // N阶矩阵快速B 형次幂
{
매트릭스 C;
memset 함수 (c.mat, 0는 sizeof (c.mat));
I 값 int;
대 (I = 1; i가 <= N; 내가 ++)
c.mat [I] [I] = 1;
반면 (b! = 0)
{
경우 (B & 1)
C = matMul (C, A, N); // C = C *는;
A = matMul (A, A, N); // A = A *
B / 2 =;
}
C를 반환;
}
INT의 main ()
{
INT 않음;
__int64 ANS;
행렬 P;
(!는 scanf ( "%의 D", N) = 0 && N) 동안
{
memset 함수 (p.mat, 0는 sizeof (p.mat));
p.mat [1] [2] = 2;
p.mat [1] [1] = p.mat [1] [3] = 1;
p.mat [2] [1] = p.mat [3] [3] = 1;
경우 (N <3)
의 printf ( "% D \ 없음", N % MOD);
또
{
p = quickMatPow (p, 3, N-2);
ANS = (p.mat [1] [1] * 2 + p.mat [1] [2] + p.mat [1] [3]) % MOD;
의 printf ( "% I64d \ n을"ANS);
}
}
0을 리턴;
}