日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

信息学奥赛一本通 1316:【例4.6】数的计数(Noip2001) | 1914:【01NOIP普及组】数的计数 | 洛谷 P1028 [NOIP2001 普及组] 数的计算

發布時間:2025/3/17 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 1316:【例4.6】数的计数(Noip2001) | 1914:【01NOIP普及组】数的计数 | 洛谷 P1028 [NOIP2001 普及组] 数的计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 1316:【例4.6】數的計數(Noip2001)
ybt 1914:【01NOIP普及組】數的計數
洛谷 P1028 [NOIP2001 普及組] 數的計算

【題目考點】

1.遞推

考慮:遞推狀態,初始狀態,遞推關系

2.記憶化遞歸

考慮:遞歸問題,遞歸關系,遞歸出口,狀態記錄

【解題思路】

解法1:

1)遞推:

  • 遞推狀態:a[i]: 數字i經過處理后可以生成的數字有多少個
  • 遞推關系:思考過程:如果要想求a[n], 對于所有k(k<n),a[k]是已知的。
    數字n左邊可以添加的數字可以有:0(不添加),1,2,…,n/2。而假設添加數字i(0≤i≤n/20 \le i \le n/20in/2),那么由數字i可以生成a[i]種數字。
    共可以生成數字個數:a[n] = a[0]+a[1]+...+a[n/2]
  • 初始狀態:a[0]左邊不添加數字,自己本身作為一個結果。a[0]的值為1。

2)記憶化遞歸:

  • 遞歸問題:求數字n經過處理后可以生成的數字有多少個,函數記為int getNum(int n)
  • 遞歸關系:思考過程:如果要想求getNum(n),可以先求getNum(k) (已知k<n)
    數字n左邊可以添加的數字可以有:0(不添加),1,2,…,n/2。而假設添加數字i(0≤i≤n/20 \le i \le n/20in/2),那么由數字i可以生成getNum(i)種數字。
    總共可以生成數字的種類數為:getNum(0)+getNum(1)+...+getNum(n/2)
  • 遞歸出口:getNum(0)表示左邊不添加數字,自己本身作為一個結果。getNum(0)的值應該為1
  • 狀態記錄:數字i能生成的數字數量

解法2:

在解法1的基礎上繼續化簡遞推公式
已知遞推關系:a[n] = a[0]+a[1]+...+a[n/2-1]+a[n/2]
那么:a[n-1] = a[0]+a[1]+...+a[(n-1)/2]

  • 如果n為偶數,那么(n-1)/2 = n/2 - 1
    a[n-1] = a[0]+a[1]+...+a[n/2-1]
    a[n] = a[n-1] + a[n/2]
  • 如果n為奇數,那么(n-1)/2 = n/2
    a[n-1] = a[0]+a[1]+...+a[n/2]
    a[n] = a[n-1]

(遞歸寫法略)

【題解代碼】

解法1:

  • 遞推, 遞推關系:a[n] = a[0]+a[1]+...+a[n/2]
#include<bits/stdc++.h> using namespace std; int a[1005];//a[i]:數字i能生成的數字數量 int main() {int n;cin >> n;a[0] = 1;for(int i = 1; i <= n; ++i){for(int j = 0; j <= i/2; ++j) a[i] += a[j];}cout << a[n];return 0; }
  • 記憶化遞歸
#include<bits/stdc++.h> using namespace std; int num[1005];//num[i]:數字i能生成的數字數量 int getNum(int k)//獲取數字k能生成的數字數量 {if(k == 0)return 1;if(num[k] > 0)//記憶化遞歸 return num[k]; int s = 0;for(int i = 0; i <= k/2; ++i)//n坐標的數字 s += getNum(i);return num[k] = s;//記憶狀態 } int main() {int n;cin >> n;cout << getNum(n);return 0; }

解法2:

  • 遞推 遞推關系:如果i是偶數a[i]=a[i-1]+a[i/2],否則a[i]=a[i-1]
#include<bits/stdc++.h> using namespace std; int a[1005];//a[i]:數字i能生成的數字數量 int main() {int n;cin >> n;a[0] = 1;for(int i = 1; i <= n; ++i){//或寫為:a[i] = i%2 == 0 ? a[i-1]+a[i/2] : a[i-1];if(i % 2 == 0)a[i] = a[i-1] + a[i/2];elsea[i] = a[i-1];}cout << a[n];return 0; }

(遞歸寫法略)

總結

以上是生活随笔為你收集整理的信息学奥赛一本通 1316:【例4.6】数的计数(Noip2001) | 1914:【01NOIP普及组】数的计数 | 洛谷 P1028 [NOIP2001 普及组] 数的计算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。