UVA11400照明系统设计&& POJ1260Peals(DP)
紫书P275: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/A
POJ http://poj.org/problem?id=1260
两个题一种类型:
UVA11400 : n个灯泡可以选择,每个灯泡有四个属性,v需要电压,k电源费用,c每个灯泡的费用和所需灯泡的数量L,每种类型的灯泡必须配一种类型的电源费用,低电压可以选择换用高电压的灯泡,计算最小费用
首先不能跨电压(1和3, 2),之前一直想不明白,其实可以这么想,1,2,3,电压是递增的,如果1和3在一起,为什么1选择3,不选择2呢?
(1)假设2和3电源费用是相同的,而3的灯泡比2的便宜,所以1选择3会有最小费用,既然如此,2也得选择3才有最优解
(2)假设2和3灯泡的价值是一样的,而3的电源费用比较低,所以1选3,同样,2选3才会有会有最优解
所以不会跨电压!
s[i]表示前i种灯泡的数量,dp[i]前i种灯泡的最小费用,dp[i] = min(dp[j] + (sum[i] - sum[j]) * c[i] + k[i]) 0 <= j < i 表示前j个用最优策略买,后面的以i的价格买
POJ 1260:珍珠的数量a和价格p,每买一种需要多买10个,低等的可以高价买,一样的意思, dp[i] = min(dp[j] + (sum[i]- sum[j] + 10) * p[i])
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int MAX = 1000 + 10; 7 const int INF = 0x3f3f3f3f; 8 struct Lamp 9 { 10 int v,k,c,l; 11 }; 12 Lamp lamp[MAX]; 13 int sum[MAX],dp[MAX]; 14 int cmp(Lamp x, Lamp y) 15 { 16 return x.v < y.v; 17 } 18 int main() 19 { 20 int n; 21 while(scanf("%d", &n) != EOF && n) 22 { 23 for(int i = 1; i <= n; i++) 24 { 25 scanf("%d%d%d%d", &lamp[i].v, &lamp[i].k, &lamp[i].c, &lamp[i].l); 26 } 27 sort(lamp + 1, lamp + n + 1, cmp); 28 memset(sum, 0, sizeof(sum)); 29 memset(dp, 0, sizeof(dp)); 30 sum[1] = lamp[1].l; 31 for(int i = 2; i <= n; i++) 32 sum[i] = sum[i - 1] + lamp[i].l; 33 dp[1] = lamp[1].c * lamp[1].l + lamp[1].k; 34 for(int i = 2; i <= n; i++) 35 { 36 int minn = INF; 37 for(int j = 0; j < i; j++) 38 { 39 minn = min(minn, dp[j] + (sum[i] - sum[j]) * lamp[i].c + lamp[i].k); 40 } 41 dp[i] = minn; 42 } 43 printf("%d\n", dp[n]); 44 } 45 return 0; 46 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 const int N = 100 + 10; 8 struct Peal 9 { 10 int a,p; 11 }; 12 Peal peal[N]; 13 int c,dp[N],sum[N]; 14 int cmp(Peal x, Peal y) 15 { 16 return x.p < y.p; 17 } 18 int main() 19 { 20 int test; 21 scanf("%d", &test); 22 while(test--) 23 { 24 scanf("%d", &c); 25 for(int i = 1; i <= c; i++) 26 { 27 scanf("%d%d", &peal[i].a, &peal[i].p); 28 } 29 //sort(peal + 1, peal + c + 1, cmp); 加排序就WA 30 memset(sum, 0, sizeof(sum)); 31 memset(dp, 0, sizeof(dp)); 32 for(int i = 1; i <= c; i++) 33 { 34 sum[i] = sum[i - 1] + peal[i].a; 35 } 36 dp[1] = ( peal[1].a + 10 ) * peal[1].p; 37 for(int i = 2; i <= c; i++) 38 { 39 int minn = INF; 40 for(int j = 0; j < i; j++) 41 { 42 minn = min(minn, dp[j] + (sum[i] - sum[j] + 10) * peal[i].p); 43 } 44 dp[i] = minn; 45 } 46 printf("%d\n", dp[c]); 47 } 48 return 0; 49 }