D. Make The Fence Great Again

[D. Make The Fence Great Again](Problem - 1221D - Codeforces)

思路

每个数最多加两次, 想明白这个直接 dp 就可以了.

\(f[i][j]:表示前i个满足题意并且第i个数加j次的最小花销.\)

#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define ull unsigned long long
#define pb push_back
#define PII pair<int, int>
#define VIT vector<int>
#define x first
#define y second
#define inf 0x3f3f3f3f
const ll INF = 1e18 + 10;
const int N = 3e5 + 10, M = N;
ll a[N], b[N];
ll f[N][3];

int main() {
    //freopen("in.txt", "r", stdin);
    IO;
    int _;
    cin >> _;
    while (_--) {
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i] >> b[i];

        for (int i = 1; i <= n; ++i)
            for (int j = 0; j <= 2; ++j)
                f[i][j] = INF;

        a[0] = -3;
        for (int i = 1; i <= n; ++i)
            for (int j = 0; j <= 2; ++j)
                for (int k = 0; k <= 2; ++k)
                    if (a[i] + j != a[i - 1] + k)
                        f[i][j] = min(f[i][j], f[i - 1][k] + j * b[i]);
        
        ll ans = INF;
        for (int i = 0; i <= 2; ++i) ans = min(ans, f[n][i]);
        cout << ans << '\n';
    }
    return 0;
}


posted @ 2021-05-25 18:55  phr2000  阅读(51)  评论(0编辑  收藏  举报