日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈

發布時間:2025/3/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 1924:【03NOIP普及組】棧
洛谷 P1044 [NOIP2003 普及組] 棧

【題目考點】

  • 遞推、遞歸
  • 【解題思路】:一維遞推

    • 設數組a,a[i]表示i個數組成的數列經過棧處理后得到的數列總數

    • 易知:a[1] = 1。特殊地,將a[0]也設為1。

    • 1~n組成數列,要經過棧處理后形成一個數列,要經歷以下幾個階段。

      • 1入棧
      • l個數字入棧出棧,經過棧處理形成數列1。(0 <= l <= n-1)
      • 1出棧
      • r個數字入棧出棧,經過棧處理形成數列2。(0 <= r <= n-1)
    • 其中l + r + 1 = n,最后得到的數列為:數列1,1,數列2

    • 由l個數字經過棧處理形成數列1,種類數為a[l],同理,由r個數字組成的數列2的種類數為a[r]。則類似"數列1,1,數列2"的數列的種類數為:a[l]*a[r]。

    • 1在最終數列中若是第1個數字,此時l為0, r為n-1。1在最終數列中若是第2個數字,此時l為1,r為n-2。將相關量列成表格,有:

    1是數列中第幾個數字lr
    10n-1
    21n-2
    n-1n-21
    nn-10

    1在每個位置時,最終數列的種類數為:a[l]*a[r]。已知r = n - 1 - l,即為a[l]*a[n-1-l]
    每種數列的種類數加和即為n個數字經過棧處理后得到的數列種類數,其值為:
    a[n]=∑l=0n?1a[l]?a[n?1?l]a[n] =\sum_{l=0}^{n-1}a[l]*a[n-1-l]a[n]=l=0n?1?a[l]?a[n?1?l]
    該公式即為遞推公式。

    【題解代碼】

    #include<bits/stdc++.h> using namespace std; int main() {int n, a[25];cin>>n;a[0] = 1;a[1] = 1;for(int i = 2; i <= n; ++i){a[i] = 0;for(int l = 0; l <= i - 1; ++l)a[i] += a[l] * a[i - 1 - l];}cout<<a[n];return 0; }

    【解題思路】:二維遞推

    設遞推狀態a[i][j]為:當操作數序列有i個數字,棧中有j個數字時,可以形成的序列數目。

    • 當操作數序列為空時,沒有數字可以入棧,只能進行出棧動作,此時可以形成的序列只有1種。即i為0時,a[i][j]=1。
    • 當棧為空時,只能進行入棧操作,所以有:當j為0時,a[i][j] = a[i-1][1];
    • 當操作數有i個,棧中有j個數時,可以有兩種操作:
      操作1: 將一個數字從操作數序列中取出,進棧,這樣做后,操作數剩余i-1個,棧中有j+1個數,可以形成a[i-1][j+1]種序列。
      操作2: 棧中棧頂數字出棧。這樣做后,操作數剩余i個,棧中有j-1個數,可以形成a[i][j-1]種序列
      所以有:a[i][j] = a[i-1][j+1] + a[i][j-1];

    【題解代碼】

    #include<bits/stdc++.h> using namespace std; int main() {int n, a[20][20];//a[i][j]:當操作數序列有i個數字,棧中有j個數字時,可以形成的序列數目。cin>>n;for(int i = 0; i <= n; ++i)for(int j = 0; j <= n; ++j){if(i == 0)a[i][j] = 1;else if(j == 0)a[i][j] = a[i-1][1];elsea[i][j] = a[i-1][j+1] + a[i][j-1];}cout<<a[n][0];return 0; }

    【解題思路】:記憶化遞歸

    思路與上述遞推大體相同,用記憶化遞歸來做。

    #include<bits/stdc++.h> using namespace std; int f[20][20]; //f[i][j]:當操作數序列有i個數字,棧中有j個數字時,可以形成的序列數目。 int seqNum(int i, int j)//求f[i][j] {if(f[i][j] == 0)//如果沒求出過f[i][j],則求一下 {if(i == 0)f[i][j] = 1;else if(j == 0)f[i][j] = seqNum(i-1, 1);elsef[i][j] = seqNum(i-1, j+1) + seqNum(i, j-1);}return f[i][j]; } int main() {int n;cin>>n;cout<<seqNum(n, 0);return 0; }

    總結

    以上是生活随笔為你收集整理的信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈的全部內容,希望文章能夠幫你解決所遇到的問題。

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