zoukankan      html  css  js  c++  java
  • Codeforces1221D. Make The Fence Great Again(dp)

    题目链接:传送门

    思路:

    仔细想一下可以发现:每个位置最多就增加2个高度。

    所以就可以有状态:

    f[i][j]表示保证前i个篱笆都是great时,第i个篱笆增加j的高度所需要的最小花费(1 <= i <= n, 0 <= j <= 2)。总共有3n个状态。

    如果i = 1,f[i][j] = a[1] * j;

    如果i > 1, f[i][j] = min{f[i-1][k] | 0 <= k <= 2 && a[i]+j != a[i-1]+k};这里的“a[i]+j != a[i-1]+k”保证了篱笆都是great的。

    答案ans = min{f[n][j] | 0 <= j <= 2}

    时间复杂度是O(n)的。


    代码:O(n)

    #include <bits/stdc++.h>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 300005
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    
    ll a[N], b[N];
    ll f[N][3];
    
    int main()
    {
        int q;
        cin >> q;
        while (q--) {
            int n; cin >> n;
            for (int i = 1; i <= n; i++) {
                read(a[i], b[i]);
                memset(f[i], 0x3f, sizeof(f[i]));
            }
            memset(f[0], 0, sizeof(f[0]));
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j < 3; j++) {
                    for (int k = 0; k < 3; k++) if (a[i-1]+j != a[i]+k) {
                        f[i][k] = min(f[i][k], f[i-1][j] + k*b[i]);
                    }
                }
            }
            ll ans = 2e18;
            for (int i = 0; i < 3; i++) {
                ans = min(ans, f[n][i]);
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    高并发下秒杀商品,必须知道的9个细节
    linux下关闭网络命令
    Linux系统模拟网络测试
    20211215
    观影大数据分析(上)
    2021冬季学期有感
    观影大数据分析(中)
    Docker安装Oracle
    2022寒假安排
    Docker安装Mongo
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/11623449.html
Copyright © 2011-2022 走看看