행렬 곱셈 (IV), 재귀 결정 문제를 분석 고속 전력 해결 행렬을 이용하여

      신속한 애플리케이션 매트릭스 전원 동작 문제 재발을 해결할 수있다. 실제로, 피사체가 직접 재귀주고 조심스럽게 신속하게 문제 해결을 가속화 문제를 분석하고 재귀 확인하고 매트릭스 전원 작업을 사용하지 않아도 때때로이다.

[실시 예 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을 리턴;
}

추천

출처www.cnblogs.com/cs-whut/p/11456718.html