2012-07-01 26 views
6

chúng ta phải tìm ra thuật ngữ thứ n của loạt bài này http://oeis.org/A028859thứ n hạn của loạt

n < = 1000000000

câu trả lời nên được modulo 1000000007

i đã viết mã nhưng lần vượt quá giới hạn khi na là số lượng lớn.

#include<iostream> 
using namespace std 

int main() 
{ 
    long long int n; 
    cin>>n; 

    long long int a,b,c; 
    a=1; 
    b=3; 

    int i; 
    for(i=3;i<=n;i++) 
    { 
     c=(2ll*(a+b))%1000000007; 
     a=b; 
     b=c; 
    } 

    cout<<c; 
} 
+2

Bất kỳ cơ hội nào bạn có thể dán vào mẫu mã sạch hơn mẫu này, sử dụng thụt lề thích hợp và tránh không gian trắng quá mức? –

+2

Điều này có liên quan gì đến lập trình động? – Mathias

+0

Hãy thử phiên bản đệ quy của thuật toán này và bạn sẽ hiểu đây là thuật toán lập trình động. Về cơ bản, chúng tôi lưu trữ các giá trị tính toán của n-1 và n-2. Hãy nói rằng, đó là một verson cơ bản của DP. –

Trả lời

9

Kỹ thuật tiêu chuẩn để giải quyết loại sự cố này là viết lại nó dưới dạng phép nhân và sau đó sử dụng exponentiation by squaring để tính toán hiệu quả các quyền hạn của ma trận.

Trong trường hợp này:

a(n+2) = 2 a(n+1) + 2 a(n) 
a(n+1) = a(n+1) 

(a(n+2)) = (2 2) * (a(n+1)) 
(a(n+1)) (1 0) (a(n) ) 

Vì vậy, nếu chúng ta định nghĩa ma trận A = [2,2; 1,0], sau đó bạn có thể tính toán thuật ngữ thứ n bằng cách

[1,0] * A^(n-2) * [3;1] 

Tất cả các thao tác này có thể được thực hiện modulo 1000000007 do đó không yêu cầu thư viện số lớn.

Nó yêu cầu phép nhân O (log (n)) 2 * 2 để tính A^N, vì vậy tổng thể phương pháp này là O (log (n)), trong khi phương thức ban đầu của bạn là O (n).

EDIT

Here là giải thích tốt và triển khai C++ của phương pháp này.

+0

[Here] (http://stackoverflow.com/a/26281100/461597) Tôi đã trả lời một câu hỏi tương tự, nhưng cũng sử dụng Định lý Euler. 1000 ... 07 là số nguyên tố, vì vậy bạn không phải tính A^N nhưng A^(N% (p-1)) là đủ. Bằng cách đó, phương thức trở thành O (1) (hoặc O (p) nhưng p là hằng số) thay vì O (log (n)). – Unapiedra

0

Khi không có đủ, bạn có thể muốn sử dụng thư viện bignum. Ví dụ: GNU MP.

+0

nhưng chúng tôi phải cung cấp câu trả lời modulo 1000000007 – user1484638

+0

Không chỉ dài ** dài ** đủ nhưng tôi tin rằng ** unsigned long int ** cũng đủ vì giá trị tối đa có thể là 4 * 10000007 <4294967295. –

+0

ok..can bạn đề xuất một cách tiếp cận cho vấn đề này – user1484638

Các vấn đề liên quan