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;
}