day-9

dp

数字三角 https://www.luogu.com.cn/problem/P1216

    cin >> n;
    for (int i = 1; i <= n; i++) 
        for (int j = 1; j <= i; j++) {
            cin >> a[i & 1][j];
            a[i & 1][j] += max(a[(i & 1) ^ 1][j - 1], a[(i & 1) ^ 1][j]);
        }
    cout << *max_element(a[n & 1], a[n & 1] + n + 1) << endl;

lcs etc https://www.luogu.com.cn/problem/P1020

  int a[maxn], dp[maxn], pd[maxn], n;
    int pl[maxn], lp[maxn];
    memset(dp, 0x3f, sizeof dp);
    for (int i = 1; i <= n; i++) {
        int pls = lower_bound(dp + 1, dp + n + 1, a[i]) - dp;
        dp[pls] = a[i];
        lp[i] = pls;

        int lsp = upper_bound(pd + 1, pd + 1 + n, a[i], greater<int>()) - pd;
        pd[lsp] = a[i];
        pl[i] = lsp;
    }

    int len1 = 0, len2 = 0;
    for (int i = 1; i <= n; i++) {
        len2 += dp[i] != 1061109567;
        len1 += (pd[i] != 0);
    }
    vector<int> vec;
    int now = len2;
    for (int i = n; i >= 1; i--) {
        if (lp[i] == now)
            vec.push_back(a[i]), now--;
    }

    reverse(vec.begin(), vec.end());
    for (auto i : vec)
        cout << i << " ";
    cout << endl;

    cout << len1
         << endl
         << len2;

分策略dp 有贪心方向 https://www.luogu.com.cn/problem/P1095

cin >> m >> s >> t;
int add = 0, ust = 0;
while (m >= 10) {
    add += 60, ust++;
    m -= 10, s -= 60, t--;
    if (s <= 0 && t >= 0) {
    YES:
        cout << "Yes" << endl;
        cout << ust << endl;
        return 0;
    }
    if (t <= 0) {
        cout << "No" << endl;
        cout << add << endl;
        return 0;
    }
}

for (int i = 0; i <= t; i++)
    for (int j = 0; j <= 20; j++)
        dp[i][j] = -1e9;
dp[0][m] = 0;

for (int it = 1; it <= t; it++) {
    for (int im = 0; im <= 20; im++) {
        if (im <= 10)
            dp[it][im] = max(dp[it - 1][im + 10] + 60, dp[it][im]);
        if (im >= 4)
            dp[it][im] = max(dp[it - 1][im - 4], dp[it][im]);
        dp[it][im] = max(dp[it - 1][im] + 17, dp[it][im]);
    }
    int mx = 0;
    for (int im = 0; im <= 20; im++) {
        mx = max(mx, dp[it][im]);
    }
    if (mx >= s) {
        ust += it;
        goto YES;
    }
}
int mx = *max_element(dp[t], dp[t] + 20);
cout << "No" << endl
     << mx + add << endl;
return 0;

更简单的写法 需要学习

#include <bits/stdc++.h>
using namespace std;
const int N = 300010;
int m, s, t, dp[N], dpt[N]; //分开计算跑步还是等待
int main()
{
    cin >> m >> s >> t;
    for (int i = 1; i <= t; i++) {
        if (m >= 10) {
            m -= 10, dp[i] = dp[i - 1] + 60;
            dpt[i] = max(dpt[i - 1] + 17, dp[i]);
        } //能闪现就闪现
        else {
            m += 4;
            dp[i] = dp[i - 1];
            dpt[i] = dpt[i - 1] + 17;
        } //不能闪现就都记录下来
    }
    for (int i = 1; i <= t; i++) {
        if (dpt[i] > dp[i])
            dp[i] = dpt[i];
        if (dp[i] >= s) {
            cout << "Yes" << endl
                 << i << endl;
            return 0;
        }
    }
    cout << "No" << endl
         << dp[t] << endl;
    return 0;
}

补题 更新在对应的多校日记里
~bsgs为啥会tle啊~
~什么时候才能学会字典树啊~
~苦露西~

posted @ 2021-07-21 23:25  naymi  阅读(47)  评论(0)    收藏  举报