zoukankan      html  css  js  c++  java
  • Codeforces 940 区间DP单调队列优化

    A

    #include <bits/stdc++.h>
    #define PI acos(-1.0)
    #define mem(a,b) memset((a),b,sizeof(a))
    #define TS printf("!!!
    ")
    #define pb push_back
    #define inf 1e9
    //std::ios::sync_with_stdio(false);
    using namespace std;
    //priority_queue<int,vector<int>,greater<int>> que; get min
    const double eps = 1.0e-8;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxm = 300;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll mod = 3e7;
    int num[105];
    int main()
    {
        int n, d;
        cin >> n >> d;
        int anser = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> num[i];
        }
        if (n == 1)
        {
            cout << 0 << endl;
            return 0;
        }
        sort(num + 1, num + 1 + n);
        int now = num[n] - num[1];
        int l = 1;
        int r = n;
        for (int i = n - 1; i >= 1; i--)
        {
            for (int j = 1; j <= n - i; j++)
            {
                if (num[j + i] - num[j] <= d)
                {
                    cout << n - i - 1 << endl;
                    return 0;
                }
            }
        }
        cout<<n-1<<endl;
        return 0;
    }
    View Code

    B

    #include <bits/stdc++.h>
    #define PI acos(-1.0)
    #define mem(a,b) memset((a),b,sizeof(a))
    #define TS printf("!!!
    ")
    #define pb push_back
    #define inf 1e9
    //std::ios::sync_with_stdio(false);
    using namespace std;
    //priority_queue<int,vector<int>,greater<int>> que; get min
    const double eps = 1.0e-8;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxm = 300;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll mod = 3e7;
    int num[105];
    int main()
    {
            ll n, k, a, b;
            cin >> n >> k >> a >> b;
            ll now = n;
            ll cost = 0;
            ll remain, aim;
            if (k == 1)
            {
                    cost += 1LL * a * (now - 1);
                    cout << cost << endl;
                    return 0;
            }
            while (now != 1)
            {
                    if (now < k)
                    {
                            cost += 1LL * a * (now - 1);
                            break;
                    }
                    remain = now % k;
                    cost += remain * a;
                    now -= remain;
                    aim = now / k;
                    cost += min(1LL * a * (now - aim), 1LL * b);
                    now = aim;
            }
            cout << cost << endl;
            return 0;
    }
    View Code

    C

    找字典序最小的比给定字符串S大的字符串T

    #include <bits/stdc++.h>
    #define PI acos(-1.0)
    #define mem(a,b) memset((a),b,sizeof(a))
    #define TS printf("!!!
    ")
    #define pb push_back
    #define inf 1e9
    //std::ios::sync_with_stdio(false);
    using namespace std;
    //priority_queue<int,vector<int>,greater<int>> que; get min
    const double eps = 1.0e-8;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxm = 300;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll mod = 3e7;
    int num[30];
    int nextt[30];
    int main()
    {
            int n, k;
            string a;
            cin >> n >> k >> a;
            for (int i = 0; i < n; i++)
            {
                    num[a[i] - 'a'] = 1;
            }
            for (int i = 0; i <= 25; i++)
            {
                    for (int j = i + 1; j <= 25; j++)
                    {
                            if (num[j])
                            {
                                    nextt[i] = j;
                                    break;
                            }
                    }
            }
            if (k > n)
            {
                    cout << a;
                    int aim;
                    for (int i = 0; i <= 25; i++)
                    {
                            if (num[i])
                            {
                                    aim = i;
                                    break;
                            }
                    }
                    char ch = 'a' + aim;
                    for (int i = 1; i <= k - n; i++)
                    {
                            cout << ch;
                    }
                    cout << endl;
            }
            else
            {
                    int aim;
                    int cur;
                    for (int i = k - 1; i >= 0; i--)
                    {
                            if (nextt[a[i] - 'a'] != 0)
                            {
                                    aim = nextt[a[i] - 'a'];
                                    cur = i;
                                    break;
                            }
                    }
                    for (int i = 0; i < cur; i++)
                    {
                            cout << a[i];
                    }
                    char ch = aim + 'a';
                    cout << ch;
                    for (int i = 0; i <= 25; i++)
                    {
                            if (num[i])
                            {
                                    aim = i;
                                    break;
                            }
                    }
                    ch = aim + 'a';
                    for (int i = 1; i <= k - cur - 1; i++)
                    {
                            cout << ch;
                    }
                    cout << endl;
            }
            return 0;
    }
    View Code

    D

    在01边界的时候更新答案范围即可

    #include <bits/stdc++.h>
    #define PI acos(-1.0)
    #define mem(a,b) memset((a),b,sizeof(a))
    #define TS printf("!!!
    ")
    #define pb push_back
    #define inf 1e9
    //std::ios::sync_with_stdio(false);
    using namespace std;
    //priority_queue<int,vector<int>,greater<int>> que; get min
    const double eps = 1.0e-8;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxm = 300;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll mod = 3e7;
    int num[100005];
    int minnum[100005];
    int maxnum[100005];
    int main()
    {
            int n;
            cin >> n;
            for (int i = 1; i <= n; i++)
            {
                    scanf("%d", &num[i]);
            }
            string a;
            cin >> a;
            for (int i = 5; i <= n; i++)
            {
                    int maxn = -1000000001;
                    for (int j = 0; j <= 4; j++)
                    {
                            maxn = max(maxn, num[i - j]);
                    }
                    maxnum[i] = maxn;
            }
            for (int i = 5; i <= n; i++)
            {
                    int minn = 1000000001;
                    for (int j = 0; j <= 4; j++)
                    {
                            minn = min(minn, num[i - j]);
                    }
                    minnum[i] = minn;
            }
            int l = -1000000000;
            int r = 1000000000;
            for (int i = 4; i <= n - 1; i++)
            {
                    if (a[i] == '1' && a[i - 1] == '0')
                    {
                            l = max(l, maxnum[i + 1] + 1);
                    }
                    if (a[i] == '0' && a[i - 1] == '1')
                    {
                            r = min(r, minnum[i + 1] - 1);
                    }
            }
            cout << l << " " << r << endl;
            return 0;
    }
    View Code

    E

    单调队列优化DP

    可以证明全局最小值<=局部最小值 所以全部块要不是一块一块的 要不就是C块里面的

    因为每一个块有两种选择 所以DP方程为dp[i]=min(dp[i-1]+num[i],dp[i-c]+pre[i]-pre[i-c]-min(num[j]) ) [i-c+1<=j<=i]

    dp[i]为到第i位最少需要的代价

    #include <bits/stdc++.h>
    #define PI acos(-1.0)
    #define mem(a,b) memset((a),b,sizeof(a))
    #define TS printf("!!!
    ")
    #define pb push_back
    #define inf 1e9
    //std::ios::sync_with_stdio(false);
    using namespace std;
    //priority_queue<int,vector<int>,greater<int>> que; get min
    const double eps = 1.0e-10;
    const double EPS = 1.0e-4;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    const int MAXN = 1e5 + 5;
    ll num[MAXN];
    int q[MAXN];
    int head, tail;
    ll dp[MAXN];
    ll pre[MAXN];
    list<int> que;
    int main()
    {
            int n, c;
            cin >> n >> c;
            for (int i = 1; i <= n; i++)
            {
                    scanf("%lld", num + i);
                    pre[i] = pre[i - 1] + num[i];
            }
            for (int i = 1; i <= n; i++)
            {
                    dp[i] = dp[i - 1] + num[i];
                    while (head >= tail && i - c >= q[tail])
                    {
                            tail++;
                    }
                    while (head >= tail && num[q[head]] > num[i])
                    {
                            head--;
                    }
                    q[++head] = i;
                    if (i >= c)
                    {
                            dp[i] = min(dp[i], dp[i - c] + pre[i] - pre[i - c] - num[q[tail]]);
                    }
            }
            cout << dp[n] << endl;
    }
    View Code
  • 相关阅读:
    价值观
    周记 改
    周记
    C语言问卷调查
    icon踩坑记录
    console.log(a)和console.log(window.a)的区别?
    记录一次微信二次分享的优化过程
    在jQuery中使用自定义属性
    10个JS技巧
    日常工作总结 2019/10/10
  • 原文地址:https://www.cnblogs.com/Aragaki/p/8612793.html
Copyright © 2011-2022 走看看