Lighting System Design UVA
阿新 • • 發佈:2018-12-09
如果要換就都換,否則都不換
列一下式子很快就可以發現,如果要換一定是不是因為燈泡價格更低,就是因為當前電源太貴,所以要換就換
紫書說的方法如下
先對燈泡屬性按照電壓由小到大的順序排序
定義d[k]為買前k種燈泡的最優解
狀態轉移方程為d[k]=d[j]+剩下的全買第k種燈泡 1<= j<k
很好理解
但其實應該還有一種方法,也要排序,排序之後,從電壓最小的開始列舉,然後往上去尋找電壓更高並且換了之後最省錢的燈泡,
然後就全換成那種燈泡,如果都虧,就不要換,最終得到的一定也是最優解,而且複雜度與上面的動態規劃方法相同
這種方法應該是貪心
兩種方法雖然複雜度相同,但是具體內涵應該不同,正如兩種演算法所介紹的那樣
動態規劃是通過對子問題的求解,最終得到最優解,問題需要具有最優子結構
而貪心是不斷的做出最優策略得到最優解,問題不一定需要具有最優子結構
這道題兩者都滿足
程式碼參考劉汝佳
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iomanip> #include<assert.h> #include<vector> #include<list> #include<map> #include<set> #include<sstream> #include<stack> #include<queue> #include<string> #include<bitset> #include<algorithm> #pragma warning(disable:4996) #define me(s) memset(s,0,sizeof(s)) #define _for(i,a,b) for(int i=(a);i<(b);++i) #define _rep(i,a,b) for(int i=(a);i<=(b);++i) #define Max(a,b) (a)>(b)?(a):(b); #define Min(a,b) (a)<(b)?(a):(b); using namespace std; typedef pair <int, int> P; typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = { 0, -1, 0, 1, -1, -1, 1, 1 }; const int dc[] = { -1, 0, 1, 0, -1, 1, -1, 1 }; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const double eps = 1e-15; const int MAXN = 1000 + 10; const int MAXT = 50 + 10; struct Node { int V, K, C, L; bool operator< (const Node b) const { return V < b.V; } }; Node Lamps[MAXN]; int n; int d[MAXN], pre[MAXN]; int main() { while (scanf("%d", &n) == 1 && n) { _rep(i, 1, n) scanf("%d%d%d%d", &Lamps[i].V, &Lamps[i].K, &Lamps[i].C, &Lamps[i].L); sort(Lamps + 1, Lamps + n + 1); pre[0] = 0; _rep(i, 1, n) pre[i] = pre[i - 1] + Lamps[i].L; d[0] = 0; for (int i = 1; i <= n; i++) { d[i] = Lamps[i].K + pre[i] * Lamps[i].C; for (int j = 1; j <= i; j++) { d[i] = min(d[i], d[j] + (pre[i] - pre[j])*Lamps[i].C + Lamps[i].K); } } cout << d[n] << endl; } }