UVa 11400- Lighting SystemDesign(DP)

来源:互联网 发布:java数组定义和初始化 编辑:程序博客网 时间:2024/05/16 07:58

UVa 11400- Lighting SystemDesign

题意:要设计一个照明系统,有n种灯泡要使用,每种灯泡有4个参数,电压V,一个电源费用K,一个灯泡的费用C,以及选择该灯泡时需要的数量L,多个同种灯泡可以共用一个电源,不同灯泡需要对应的电源,电压低的灯泡可以用电压高的灯泡代替,求设计这个照明系统的最低花费。

 

分析:问题求解需要得到2个结论。

1、:一种灯泡,要么全选,要么全不选,证明:设有两种灯泡,一共选择x个,如果第一种选择y个,那么总花费为k1+k2+(C2-C1)*y+C2*x..①,如果只选择第一个,花费为K1+C1*x…②,全选第二个,花费为K2+C2*x…③,①式与后面②③做差可知总有一个大于0,即总存在更小的方案,不论C1与C2,X为何值,多种灯泡同理可证。

2、选择前i种灯泡时,如果要替换,只会替换一个连续区间的灯泡种类,即全部替换j+1到i-1为i这种灯泡。证明:如果J到i当中有一种灯泡x不替换,其他的全部替换为第i种,那么必然是选择x这种灯泡会更优,那么最优方案中j+1到x中这些灯泡应该被替换为x这种,而不应该替换为i这种灯泡,与假设矛盾,所以只会替换一连续区间的灯泡。


有了以上两个结论,便可以设计状态及转移方程了,设dp[i]为选前i种灯泡的最小花费,那么根据决策共有i种状态转移, dp[i] = min(dp[j]+(sum[i]-sum[j])*la[i].c+la[i].k,dp[i]),sum数组为灯泡数量的前缀和,转移方程类似于最长上升子序列问题,难怪紫书上面这个例题放在LIS问题之后.......

做这个题的时候,想了各种dp方程,要么难以转移,要么会漏解,后面无奈去参考了下紫书的分析,才发现没有这么直接….想来也对,很多题都是这样,没有根据题目条件,通过一定的分析,得到某些结论,那么问题便无法求解,突然才知道数学能力的重要性,这是我的一个很大的不足,通过这题也更加说明了知识才是基础!!!

#include <cstdio>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#define LL long long#define INF 0x3f3f3f3f#define N 1010using namespace std;int sum[N], dp[N];struct lamp{    int v, k, c, l;}la[N];inline int cmp(lamp x, lamp y) {return x.v < y.v;}int main(){    int n;    while (scanf("%d", &n), n){        for (int i = 1; i <= n; i++) scanf("%d %d %d %d", &la[i].v, &la[i].k, &la[i].c, &la[i].l);        sort(la+1, la+1+n, cmp);        for (int i = 1; i <= n; i++) sum[i] = sum[i-1]+la[i].l;        for (int i = 1; i <= n; i++){            dp[i] = INF;            for (int j = 0; j < i; j++) dp[i] = min(dp[j]+(sum[i]-sum[j])*la[i].c+la[i].k, dp[i]);        }        printf("%d\n", dp[n]);    }    return 0;}

0 0
原创粉丝点击