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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

洛谷【算法1-4】递推与递归

發布時間:2025/3/19 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷【算法1-4】递推与递归 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P1255 數樓梯

對于 100% 的數據,1≤N≤5000。

  • 高精度斐波那契
#include <iostream> using namespace std;const int N = 5003;int len = 1; int f[N][N];int main() {int n; scanf("%d", &n);f[1][1] = 1; f[2][1] = 2;for (int i = 3; i <= n; i ++ ){for (int j = 1; j <= len; j ++ )f[i][j] = f[i - 1][j] + f[i - 2][j];for (int j = 1; j <= len; j ++ ){f[i][j + 1] += f[i][j] / 10;f[i][j] %= 10;if (f[i][len + 1]) len ++ ;}}for (int i = len; i; i -- ) printf("%d", f[n][i]); }

P1002 [NOIP2002 普及組] 過河卒

對于100% 的數據,1≤n,m≤20,0≤ 馬的坐標≤20。

  • 坐標原點從0開始,不方便,因此偏移加一
  • 又發現馬涉及到的坐標即使偏移1還是可能越界,因此,偏移2
  • 關于馬,只要讓它的方案數為0即可,這樣即使轉移方程中涉及到了馬,也只是加了0
#include <iostream> using namespace std;const int N = 30;typedef long long ll;int dx[8] = {-2, -2, -1, 1, 2, 2, 1, -1}; int dy[8] = {-1, 1, 2, 2, 1, -1, -2, -2};ll f[N][N]; bool st[N][N];int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);int bx, by, mx, my; cin >> bx >> by >> mx >> my;bx += 2, by += 2, mx += 2, my += 2;st[mx][my] = true;for (int i = 0; i < 8; i ++ ){int x = mx + dx[i], y = my + dy[i];st[x][y] = true;}f[2][2] = 1;for (int i = 2; i <= bx; i ++ )for (int j = 2; j <= by; j ++ ){if (i == 2 && j == 2) continue;if (st[i][j]) continue;f[i][j] = f[i - 1][j] + f[i][j - 1];}cout << f[bx][by]; }

P1044 [NOIP2003 普及組] 棧

輸入文件只含一個整數 n(1≤n≤18)。

  • 遞歸 / 記憶化搜索寫法
    看數據dfs可能超時,因此想到記憶化搜索
    記憶化搜索,因此,定義一個二維數組f[i][j]表示隊列里還有i個數,棧里還有j個數,f[i][j]表示此時的情況數,自然,在f[i][j]有值的情況下就返回
    遞歸的邊界條件,隊列中沒有數了,就只剩這一種情況了,返回1
    如果棧空,不能彈出棧內元素,只能進棧一次;棧不空,此時可以出棧一次或者進棧一次
#include <iostream> using namespace std;typedef long long ll;const int N = 20;ll f[N][N];ll dfs(int que, int stk) {if (f[que][stk]) return f[que][stk];if (!que) return 1;if (stk) f[que][stk] += dfs(que, stk - 1);f[que][stk] += dfs(que - 1, stk + 1);return f[que][stk]; }int main() {int n; scanf("%d", &n);printf("%lld", dfs(n, 0)); }

P1028 [NOIP2001 普及組] 數的計算

一個正整數 n(n≤1000)。

  • 打表方法 :
#include <iostream> using namespace std;typedef long long ll;ll dfs(int u) {if (u == 1)ll tot = 1;for (int i = 1; i <= u / 2; ++ i) {tot += dfs(i);}return tot; }int main() {cout << "a[1001]={";for (int i = 1; i <= 1001; ++ i) {cout << dfs(i) << ',';}cout << "}"; } f[1] = 1 f[2] = f[1] + 1 f[3] = f[1] + 1 f[4] = f[1] + f[2] + 1 f[5] = f[1] + f[2] + 1 #include <iostream> using namespace std;typedef long long ll;const int N = 1010;ll f[N];int main() {int n;cin >> n;f[1] = 1;for (int i = 1; i <= n; ++ i) {f[i] = 1;for (int j = 1; j <= i / 2; ++ j) {f[i] += f[j];}}cout << f[n]; }

P1464 Function

保證輸入的數在[?9223372036854775808,9223372036854775807]之間,并且是整數。

  • 用記憶化搜索的時候要注意下標有沒有可能為負數
  • 不要寫成 return f[a][b][c] = dfs(a - 1, b, c) + ... 的形式,return最后再寫
#include <iostream> using namespace std;typedef long long ll;ll f[25][25][25];ll dfs(ll a, ll b, ll c) {if (a <= 0 || b <= 0 || c <= 0) return 1;if (f[a][b][c]) return f[a][b][c];ll t;if (a > 20 || b > 20 || c > 20) t = dfs(20, 20, 20);else if (a < b && b < c) t = dfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c);else t = dfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1);f[a][b][c] = t;return f[a][b][c]; }int main() {ll a, b, c;while (scanf("%lld%lld%lld", &a, &b, &c) == 3) {if (a == -1 && b == -1 && c == -1) break;printf("w(%lld, %lld, %lld) = ", a, b, c);if (a > 21) a = 21;if (b > 21) b = 21;if (c > 21) c = 21;printf("%lld\n", dfs(a, b, c));} }

P1928 外星密碼

對于 100%的數據:解壓后的字符串長度在 20000 以內,最多只有十重壓縮。
保證 有且僅有 數字字母和 [ 和 ]

  • 多重壓縮,交給遞歸
  • 特殊:以下代碼我在自己的編譯器(Xcode)上是無法運行的,編譯器顯示函數中必須任何條件都有返回值,而這個代碼本身不滿足這個條件,由于題目數據保證必然有[和],實際運行沒有問題
#include <iostream> using namespace std;string dfs() {char ch;string res = "", s = "";while (cin >> ch) {if (ch == '[') {int k;cin >> k;s = dfs();while (k -- ) {res += s;}} else if (ch == ']') {return res;} else {res += ch;}} }int main() {cout << dfs(); }

P2437 蜜蜂路線

對于100%的數據,M,N≤1000

  • 高精度
  • 答案是f[n - m + 1],因為從m走到n相當于從1走到n-m+1
#include <iostream> using namespace std;const int N = 1010;int f[N][N]; int len = 1;int main() {int m, n;cin >> m >> n;f[1][1] = 1;f[2][1] = 1;for (int i = 3; i <= n - m + 1; ++ i) {for (int j = 1; j <= len; ++ j) {f[i][j] = f[i - 1][j] + f[i - 2][j];}for (int j = 1; j <= len; ++ j) {f[i][j + 1] += f[i][j] / 10;f[i][j] %= 10;}if (f[i][len + 1]) len ++ ;}for (int i = len; i; i -- )cout << f[n - m + 1][i]; }

P1164 小A點菜

正數aia_iai?可以有相同的數字,每個數字均在1000以內;保證答案的范圍在int之內。

  • f[i][j]表示在考慮前i個物品的情況下,價格 恰好 是j的 方案數
  • 轉移 :
    1.買當前這個,f[i][j] += f[i - 1][j - a[i]]
    2.不買當前這個,f[i][j] += f[i - 1][j]
    3.其實還有一種情況,就是如果買當前這個,且當前這個的價格恰好等于j,而f[i][0]沒有被初始化就是0,實際上應該+1的,因此,我們初始化所有的f[i][0]為1
#include <iostream> using namespace std;int f[110][10010]; int a[110];int main() {int n, m;cin >> n >> m;for (int i = 1; i <= n; ++ i)cin >> a[i];for (int i = 0; i <= n; ++ i) {f[i][0] = 1;}for (int i = 1; i <= n; ++ i) {for (int j = 1; j <= m; ++ j) {if (j >= a[i]) f[i][j] += f[i - 1][j - a[i]];f[i][j] += f[i - 1][j];}}cout << f[n][m]; }
  • 由于每次f數組的第一維都只用到了i-1,因此可以給f數組降維,不要忘了第二重循環要倒著來
#include <iostream> using namespace std;int f[10010]; int a[110];int main() {int n, m;cin >> n >> m;for (int i = 1; i <= n; ++ i)cin >> a[i];f[0] = 1;for (int i = 1; i <= n; ++ i) {for (int j = m; j >= a[i]; -- j)f[j] += f[j - a[i]];}cout << f[m]; }

P1036 [NOIP2002 普及組] 選數

第一行兩個空格隔開的整數 n,k(1≤n≤20,k<n)

  • 選擇k個數中每個數所填的數
  • (100個數中選50個)去重 -> 不降原則(這道題不會選同一個數組,所以這里的 不降原則不能“平”)
#include <iostream> #include <cmath> using namespace std;bool is_prime(int x) {double t = sqrt(x);for (int i = 2; i <= t; ++ i) {if (x % i == 0)return false;}return true; }int a[25]; int n, k, ans;void dfs(int sel, int sum, int st) {if (sel == k + 1) {if (is_prime(sum))ans ++ ;return ;}for (int i = st; i <= n; ++ i) {dfs(sel + 1, sum + a[i], i + 1);}return ; }int main() {cin >> n >> k;for (int i = 1; i <= n; ++ i)cin >> a[i];dfs(1, 0, 1);cout << ans; }

P1990 覆蓋墻壁

一個整數N(1<=N<=1000000),表示墻壁的長。

  • 取后四位,也就是說%1e4
#include <iostream> using namespace std;const int N = 1e6 + 10; const int mod = 1e4;int f[N], g[N];int main() {int n;cin >> n;f[0] = 1; f[1] = 1;g[0] = 0; g[1] = 1;for (int i = 2; i <= n; ++ i) {f[i] = ((f[i - 1] + f[i - 2]) % mod + 2 * g[i - 2] % mod) % mod;g[i] = f[i - 1] + g[i - 1] % mod;}cout << f[n]; }

P3612 [USACO17JAN]Secret Cow Code S

該字符串包含最多30個大寫字母,并 N≤1018\leq10^{18}1018

總結

以上是生活随笔為你收集整理的洛谷【算法1-4】递推与递归的全部內容,希望文章能夠幫你解決所遇到的問題。

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