1. 程式人生 > >【2018/10/08測試T1】【SOJ 2175】斐波那契

【2018/10/08測試T1】【SOJ 2175】斐波那契

【題目】

題目描述:

斐波那契數列又稱兔子數列,可以通過以下方式產生:一開始只有一隻兔子,一個月之後這隻兔子每個月會繁殖出另一隻兔子。之後每隻兔子出生後都按照以上規則繁殖。我們把每個月的兔子的數量作為數列中的數就可以得到斐波那契數列。

現在草原上有 nn 只兔子排成一排,每隻兔子有一個繁殖能力 aia_i。小 F 想把這些兔子分組,要求一個組內的兔子必須是連續的一段。而且因為兔子們不太喜歡兔子數列,所以組內任意兩隻兔子的繁殖能力的和不能在兔子數列中出現。

現在小 F 想讓這些兔子的分組數量儘可能少,但是兔子很多,他算不過來,於是他找到了你,想讓你告訴他最少的分組數量是多少。

輸入格式:

第一行一個整數 nn,表示兔子的個數。 接下來一行 nn 個數,依次表示 aia_i

輸出格式:

輸出一個數,表示最小的分組數量。

樣例資料:

輸入 5 1 5 2 6 7

輸出 4

備註: 【樣例解釋】 最優分組的一種為:{1}, {5, 2}, {6}, {7}。

【資料範圍】 對於 10% 的資料,nn ≤ 20。 對於 30% 的資料,nn ≤ 300。 對於 60% 的資料,nn ≤ 1000。 對於 100 % 的資料,nn ≤ 100000, aia_i10910^9

【分析】

其實這道題也不難,主要是思路沒有想對,只得了60分

我們用貪心做,從左往右貪心,當找到第一個不符合條件的數(即與前面的數加起來是兔子序列中的數)就斷開,前面的分成一組,然後又從這個數開始貪心,直到分完

由於 intint 範圍內斐波那契數列中只有四十幾個,所以我們列舉每個斐波那契數,做差,然後判斷差值有沒有出現過即可

由於 aia_i10910^9,用陣列存顯然是不行的,我們就用 mapmap 來存

時間複雜度 O(45nlog  n45 * n * log\;n

【程式碼】

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace
std; int a[N],f[N]; map<int,bool>vis; int main() { // freopen("f.in","r",stdin); // freopen("f.out","w",stdout); int n,i,j,ans=1; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d",&a[i]); f[1]=1,f[2]=2; for(i=3;i<=45;++i) f[i]=f[i-1]+f[i-2]; for(i=1;i<=n;++i) { for(j=1;j<=45;++j) { int num=f[j]-a[i]; if(num>0&&vis[num]) { ans++; vis.clear(); vis[a[i]]=true; break; } } if(j>45) vis[a[i]]=true; } printf("%d",ans); // fclose(stdin); // fclose(stdout); return 0; }