zoukankan      html  css  js  c++  java
  • 动态规划专题

    最长上升子序列:

    dp = [1 for i in range(1007)]
    n = eval(input())
    a = list(map(int, input().split()))
    for i in range(n):
    for j in range(0, i):
    if a[j] <= a[i]:
    dp[i] = max(dp[i], dp[j] + 1)

    print(max(dp))

    最长公共子序列:

    s1 = input()
    s2 = input()
    n = len(s1)
    m = len(s2)
    dp = [[0 for j in range(m + 1)] for i in range(n + 1)]
    for i in range(n):
        for j in range(m):
            if s1[i] == s2[j]:
                dp[i + 1][j + 1] = dp[i][j] + 1
            else:
                dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j])
    
    print(max(max(dp)))

     二进制优化多重背包:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e3 + 7;
    int vv[maxn], ww[maxn], s[maxn], N, V, v[maxn];
    int dp[maxn], w[maxn];
    int get(int x) {
        int p = 0, tot = 0;
        for (int i = 0; ; i++) {
            tot += pow(2, i);
            if (tot <= x) {
                p = i;
            }
            if (tot >= x)
                break;
        }
        return p;
    }
    int main() {
        int cnt = 0;
        cin >> N >> V;
        for (int i = 0; i < N; i++) {
            cin >> vv[i] >> ww[i] >> s[i];
        }
        for (int i = 0; i < N; i++) {
            int p = get(s[i]);
            int R = s[i] - pow(2, p + 1) + 1;
            for (int j = 0; j <= p; j++) {
                v[++cnt] = pow(2, j) * vv[i], w[cnt] = ww[i] * pow(2, j);
            }
            if (R)
                v[++cnt] = R * vv[i], w[cnt] = ww[i] * R;
    
        }
        for (int i = 1; i <= cnt; i++) {
            for (int j = V; j >= v[i]; j--) {
                dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
            }
        }
        cout << *max_element(dp, dp + 1 + V) << endl;
        return 0;
    }

    多重背包判断能否组成问题:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e2 + 7;
    int A[maxn], C[maxn];
    bool dp[maxn * 1000];
    int used[maxn * 1000];
    int main() {
        int N, M;
        while (cin >> N >> M && N && M) {
            memset(dp, false, sizeof(dp));
            for (int i = 1; i <= N; i++)
                cin >> A[i];
            for (int i = 1; i <= N; i++)
                cin >> C[i];
            dp[0] = true;
            for (int i = 1; i <= N; i++) {
                memset(used, 0, sizeof(used));
                for (int j = A[i]; j <= M; j++) {
                    if (!dp[j] && dp[j - A[i]] && used[j - A[i]] + 1 <= C[i])
                        dp[j] = true, used[j] = used[j - A[i]] + 1;
                }
            }
            int res = 0;
            for (int i = 1; i <= M; i++) {
                res += dp[i];
            }
            cout << res << endl;
        }
        return 0;
    }

    分组背包问题:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e2 + 7;
    int N, V, s[maxn], v[maxn][maxn], w[maxn][maxn], dp[maxn];
    int main() {
        cin >> N >> V;
        for (int i = 1; i <= N; i++) {
            cin >> s[i];
            for (int j = 1; j <= s[i]; j++)
                cin >> v[i][j] >> w[i][j];
        }
        for (int i = 1; i <= N; i++) {
            for (int j = V; j >= 0; j--) {
                for (int k = 1; k <= s[i]; k++) {
                    if (j >= v[i][k])
                        dp[j] = max(dp[j - v[i][k]] + w[i][k], dp[j]);
                }
            }
        }
        cout << *max_element(dp, dp + 1 + V) << endl;
        return 0;
    }

    区间dp问题:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 3e2 + 7;
    int dp[maxn][maxn], a[maxn], sum[maxn], N;
    int main() {
        cin >> N;
        memset(dp, 0x3f, sizeof(dp));
        for (int i = 1; i <= N; i++) {
            cin >> a[i];
            sum[i] = sum[i - 1] + a[i];
            dp[i][i] = 0;
        }
        for (int len = 2; len <= N; len++) {
            for (int l = 1; l <= N - len + 1; l++) {
                int r = l + len - 1;
                for (int k = l; k < r; k++)
                    dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r]);
                dp[l][r] += sum[r] - sum[l - 1];
            }
        }
        cout << dp[1][N] << endl;
        return 0;
    }

     树形dp入门:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 6e3 + 7;
    vector<int> G[maxn];
    int dp[maxn][2], h[maxn], in[maxn];
    void Dp(int u) {
        dp[u][0] = 0;
        dp[u][1] = h[u];
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            Dp(v);
            dp[u][0] += max(dp[v][1], dp[v][0]);
            dp[u][1] += dp[v][0];
        }
    }
    int main() {
        int n, u, v;
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> h[i];
        for (int i = 1; i < n; i++) {
            cin >> v >> u;
            G[u].push_back(v);
            in[v]++;
        }
        int root = -1;
        for (int i = 1; i <= n; i++) {
            if (!in[i]) root = i;
        }
        Dp(root);
        cout << max(dp[root][0], dp[root][1]) << endl;
        return 0;
    }

     ST算法:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 7;
    const int maxm = 32;
    int dp[maxn][maxm], n, a[maxn];
    void ST_work() {
        for (int i = 1; i <= n; i++)
            dp[i][0] = a[i];
        int t = log(n) / log(2) + 1;
        for (int j = 1; j < t; j++) {
            for (int i = 1; i <= n - (1 << j) + 1; i++) {
                dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    int ST_query(int l, int r) {
        int t = log(r - l + 1) / log(2);
        return max(dp[l][t], dp[r - (1 << t) + 1][t]);
    }
    void init() {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        ST_work();
    }
    void query() {
        int m, l, r;
        cin >> m;
        while (m--) {
            cin >> l >> r;
            cout << ST_query(l, r) << endl;
        }
    }
    int main() {
        init();
        query();
        return 0;
    }

     最大上升子序列:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    int a[maxn], dp[maxn], n;
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        fill(dp, dp + maxn, inf);
        for (int i = 1; i <= n; i++) {
            *upper_bound(dp + 1, dp + 1 + n, a[i]) = a[i];
        }
        cout << lower_bound(dp + 1, dp + 1 + n, inf) - dp - 1 << endl;
        return 0;
    }
  • 相关阅读:
    ASP.NET中 CheckBox(复选框)的使用
    ASP.NET中 HyperLink(超链接)的使用
    ASP.NET中 HiddenField(隐藏控件)的使用
    ASP.NET中 ImageButton(图片按钮)的使用
    ASP.NET中 PlaceHolder(占位文本)的使用
    ASP.NET中 FileUpload(上传控件)的使用
    Metro Style App开发快速入门 之XML文件读取,修改,保存等操作
    .NET Framework 4.5新特性
    一个10年程序员给大家的忠告
    SQLite快速入门二表、视图的创建、修改、删除操作
  • 原文地址:https://www.cnblogs.com/SwiftAC/p/12374569.html
Copyright © 2011-2022 走看看