UVa 11400 - Lighting System Design (dp)
阿新 • • 發佈:2021-07-22
題目連結:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2395
要換燈泡的話,一定是這個種類的全換,將燈泡按電壓排序,如果有燈的種類要替換成燈 \(i\),那麼燈 \(i\) 的 \(c[i]*l[i]+k[i]\) 一定是這段區間中最小的,最終替換成的所有燈泡的 \(c[i]*l[i]+k[i]\) 一定是遞增的,如下圖
紅線是燈泡原來的值,黑框是替換以後的值的樣子
所以我們就可以考慮 \(dp\),令 \(dp[i]\) 表示前 \(i\)
其中 \(s[i]\) 表示前 \(i\) 個燈泡的總數量
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1010; int n; int s[maxn], dp[maxn]; struct Lamp{ int v, k, c, l; bool operator < (const Lamp &x) const{ return v < x.v; } }a[maxn]; ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ while(scanf("%d", &n) == 1 && n){ for(int i = 1 ; i <= n ; ++i){ scanf("%d%d%d%d", &a[i].v, &a[i].k, &a[i].c, &a[i].l); } sort(a + 1, a + 1 + n); s[0] = 0; for(int i = 1 ; i <= n ; ++i) s[i] = s[i-1] + a[i].l; memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; for(int i = 1 ; i <= n ; ++i){ for(int j = 0 ; j < i ; ++j){ dp[i] = min(dp[i], dp[j] + (s[i] - s[j]) * a[i].c + a[i].k); } } printf("%d\n", dp[n]); } return 0; }