數的計數【Noip2001】


【題目描述】

我們要求找出具有下列性質數的個數(包括輸入的自然數n)。先輸入一個自然數n(n≤1000),然后對此自然數按照如下方法進行處理:

不作任何處理;

在它的左邊加上一個自然數,但該自然數不能超過原數的一半;

加上數后,繼續按此規則進行處理,直到不能再加自然數為止。

【輸入】

自然數n(n≤1000)。

【輸出】

滿足條件的數。

【輸入樣例】

6

【輸出樣例】

6

看完題目以及樣例輸入與輸出,本人便把這6種情況列舉了出來:
  1. 6
  2. 16
  3. 26
  4. 126
  5. 36
  6. 136

那么就特別簡單,設一個函數Dfs,一直遞歸“1~參數/2”,每次遞歸的同時增加符合條件的數的數量即可:

【方法一】遞歸f(n)=1+f(1)+f(2)+···+f(n/2)
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<iomanip> #include<string> using namespace std; int num=0; int dfs(int n){ num++; for(int i=1;i<=n/2;i++){ dfs(i); } } int main(){ int n; cin>>n; dfs(n); cout<<num; }

提交后,情況如下:
測試點 1:    答案正確     460KB     3MS 

測試點 2:     答案正確     464KB     3MS 

測試點 3:     答案正確     456KB     2MS 

測試點 4:     答案正確     464KB     2MS 

測試點 5:     答案正確     476KB     4MS 

測試點 6:     答案正確     456KB     2MS 

測試點 7:     答案正確     464KB     2MS 

測試點 8:     答案正確     452KB     2MS 

測試點 9:     答案正確     468KB     310MS 

測試點10:     運行超時     456KB     994MS 
 
反正第9、10個點不知道已經跑到哪去了,耗時十分離譜

那么,往下看

 

【方法二】記憶化搜索

#include<iostream> #include<cstdio> #include<iomanip> #include<cstring> using namespace std; const int SB=-1438; int num[2000]; void Dfs(int n){ if(num[n]!=SB)return;//前面有結果了就不用再算 num[n]=1; for(int i=1;i<=n/2;i++){ Dfs(i); num[n]+=num[i];//統計數量,so easy } } int main(){ int n; cin>>n; for(int i=1;i<=n;i++)num[i]=SB; Dfs(n); cout<<num[n];
return 0; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM