生活随笔
收集整理的這篇文章主要介紹了
[蓝桥杯][算法训练VIP]摆动序列(深搜+回溯||动态规划)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
如果一個序列滿足下面的性質,我們就將它稱為擺動序列:
序列中的所有數都是不大于k的正整數;序列中至少有兩個數。序列中的數兩兩不相等;如果第i – 1個數比第i – 2個數大,則第i個數比第i – 2個數小;如果第i – 1個數比第i – 2個數小,則第i個數比第i – 2個數大。
比如,當k = 3時,有下面幾個這樣的序列:
1 2
1 3
2 1
2 1 3
2 3
2 3 1
3 1
3 2
一共有8種,給定k,請求出滿足上面要求的序列的個數。
輸入
輸入包含了一個整數k。(k< =20)
輸出
輸出一個整數,表示滿足要求的序列個數。
樣例輸入
3
樣例輸出
8
思路:一開始以為是記憶化搜索,但是沒想出怎么記憶化,就暴力dfs+回溯試了一下,發現數列收斂的很快,沒有特別長的那種,所以時間復雜度是允許的(k<=20)。
代碼如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std
;const int maxx
=2e1+1;
int a
[maxx
],vis
[maxx
];
int n
;inline void dfs(int num
,int &ans
)
{if(num
>n
) return ;if(num
>=2){ans
++;if(a
[num
]>a
[num
-1]) {for(int i
=a
[num
-1]-1;i
>=1;i
--){if(vis
[i
]==0){a
[num
+1]=i
;vis
[i
]=1;dfs(num
+1,ans
);vis
[i
]=0;a
[num
+1]=i
;}}}else{for(int i
=a
[num
-1]+1;i
<=n
;i
++){if(vis
[i
]==0){a
[num
+1]=i
;vis
[i
]=1;dfs(num
+1,ans
);vis
[i
]=0;a
[num
+1]=0;}}}}else{for(int i
=a
[num
]-1;i
>=1;i
--){if(vis
[i
]==0){a
[num
+1]=i
;vis
[i
]=1;dfs(num
+1,ans
);vis
[i
]=0;a
[num
+1]=0;}}for(int i
=a
[num
]+1;i
<=n
;i
++){if(vis
[i
]==0){a
[num
+1]=i
;vis
[i
]=1;dfs(num
+1,ans
);vis
[i
]=0;a
[num
+1]=0;}}}
}
int main()
{scanf("%d",&n
);int ans
=0;memset(vis
,0,sizeof(vis
));for(int i
=1;i
<=n
;i
++){a
[1]=i
;vis
[i
]=1;dfs(1,ans
);vis
[i
]=0;}cout
<<ans
<<endl
;return 0;
}
如果k再大一點,dfs就不是那么好了,因為回溯耗時也很大。那么我們考慮dp的方式。我們可以根據dfs的結果,建立一個表,在里面尋找規律。如下圖所示(圖片來源):
縱坐標代表的是k的取值,橫坐標代表的是在這k個數中選取的數的個數。
我們可以發現,橫坐標為2的時候,答案總是(k-1)*k。橫坐標再大的時候,我們就可以發現規律了。
狀態轉移方程:dp[i][j]=dp[i-1][j]+dp[i-1][j-1].
代碼如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std
;const int maxx
=2e2+100;
int dp
[maxx
][maxx
];
int n
;int main()
{scanf("%d",&n
);for(int i
=2;i
<=n
;i
++) dp
[i
][2]=(i
-1)*i
;for(int j
=3;j
<=n
;j
++){for(int i
=3;i
<=n
;i
++) dp
[i
][j
]=dp
[i
-1][j
]+dp
[i
-1][j
-1];}int ans
=0;for(int i
=2;i
<=n
;i
++) ans
+=dp
[n
][i
];cout
<<ans
<<endl
;return 0;
}
時間復雜度僅僅為O(n^2)。
努力加油a啊,(o)/~
總結
以上是生活随笔為你收集整理的[蓝桥杯][算法训练VIP]摆动序列(深搜+回溯||动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。