Cpp環境【Vijios1093】文科生的悲哀

【問題描述】
  化學不及格的Matrix67無奈選擇了文科。他必須硬着頭皮準備一次又一次的文科考試。
  在這一學期一共有n次文科考試,考試科目有4種,分別爲政治、歷史、地理和綜合。每次考哪一科是不定的,因此在考試前Matrix67不知道應該去複習哪一科的功課。他希望能預測出下一次可能考的科目。於是,他收集到了以往的文科考試的資料。從以往的考試中,他發現了這樣幾個規律:

   1.如果這次考的是政治,那麼下一次一定會考歷史;
   2.如果這次考的是綜合,那麼下一次一定會考地理;
   3.如果這次考的是歷史,那麼下一次要麼考政治,要麼考地理;
   4.如果這次考的是地理,那麼下一次要麼考歷史,要麼考綜合。

  Matrix67已經知道,本學期的第一次考試科目爲政治。他打算擬定一個可以應對所有可能情況的應考複習計劃。因此,他想知道,整個學期有多少種可能的考試科目安排滿足以上規律。

【輸入格式】  

  一個正整數n,代表本學期總的考試次數。輸入數據保證n<=10000。

【輸出格式】  

  一個正整數,表示符合規律的科目安排方案的總數。考慮到這個結果可能會很大,因此你只需要輸出它mod 7654321的值即可。

【輸入樣例】  

5

【輸出樣例】  

5

【樣例解釋】  

當n=5時,有以下5種方案滿足要求:
- 政治–>歷史–>政治–>歷史–>政治
- 政治–>歷史–>政治–>歷史–>地理
- 政治–>歷史–>地理–>歷史–>政治
- 政治–>歷史–>地理–>歷史–>地理
- 政治–>歷史–>地理–>綜合–>地理

【數據範圍】  

n<=10000

【來源】    

Matrix67 根據經典問題改編
Vijos題庫 原題傳送矩陣
重慶一中題庫 原題傳送矩陣

【思路梳理】

不難想到模擬,運用遞推的思想,計算所有的方案數總和。那麼這樣做的時間複雜度只有O(n),目測應該能夠AC通過所有的數據。
思考一下高效算法,首先我們可以列出如下的表格和流程圖:
這裏寫圖片描述
這裏寫圖片描述
顯然第i次考試對應的是斐波那契數列的第i項,所以只需要遞歸地寫出求斐波那契數列第i項的函數即可,使用記憶化搜索,時間複雜度降低爲O(logn),能夠輕鬆通過所有數據。

【Cpp代碼】
#include<cstdio>
#include<iostream>
#define maxn 10005
using namespace std;
long long d[maxn];//使用int和long long都無妨
int n;

long long mod(long long x)
{
    return x%7654321;//個人習慣,將取模寫作函數
}

long long f(int x)
{
    if(x==1)    return d[1]=1;
    if(x==2)    return d[2]=1;
    if(d[x])    return d[x];//直接查表,記憶化搜索 

    return d[x]=mod(mod(f(x-2))+mod(f(x-1)));
}

int main()
{
    scanf("%d",&n);//簡單分析一下就會發現是斐波那契數列,求的是該數列的第n項 

    cout<<f(n);
    return 0;
}
發佈了59 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章