uva11400 lighting system design

来源:互联网 发布:软件开发助理工程师 编辑:程序博客网 时间:2024/06/06 12:20

You are given the task to design a lighting system for a huge
conference hall. After doing a lot of calculation and sketching, you
have gured out the requirements for an energy-efficient design that
can properly illuminate the entire hall. According to your design, you
need lamps of n different power ratings. For some strange current
regulation method, all the lamps need to be fed with the same amount
of current. So, each category of lamp has a corresponding voltage
rating. Now, you know the number of lamps and cost of every single
unit of lamp for each category. But the problem is, you are to buy
equivalent voltage sources for all the lamp categories. You can buy a
single voltage source for each category (Each source is capable of
supplying to in nite number of lamps of its voltage rating.) and
complete the design. But the accounts section of your company soon
gures out that they might be able to reduce the total system cost by
eliminating some of the voltage sources and replacing the lamps of
that category with higher rating lamps. Certainly you can never
replace a lamp by a lower rating lamp as some portion of the hall
might not be illuminated then. You are more concerned about
money-saving than energy-saving. Find the minimum possible cost to
design the system. Input Each case in the input begins with n (1  n 
1000), denoting the number of categories. Each of the following n
lines describes a category. A category is described by 4 integers - V
(1  V  132000), the voltage rating, K (1  K  1000), the cost of a
voltage source of this rating, C (1  C  10), the cost of a lamp of
this rating and L (1  L  100), the number of lamps required in this
category. The input terminates with a test case where n
= 0. This case should not be processed. Output For each test case, print the minimum possible cost to design the system.

首先需要注意两点。第一,每种电压的灯泡要么全换,要么不换。如果换了一部分,也就是两种电压都买了,那就选单价少的一种灯泡全买。在这之后或许还能少买一种电源,一定会更省钱。
第二,换到某一电压的灯泡一定是在他之前一段连续的区间。如果中间有断开的话,那么断点以前的灯泡和断点做同样的事会更优【换到另一个电压上,或者就是断电本身】。
之后,我们便可以知道如何DP了。
设dp[i]是1..i全部“内部消化”的最小值,也就是没有灯泡会换成i以后的电源。由于最后到n,一定是1..n“内部消化”,所以不会丢失解。那么首先i电源一定安了(否则i灯泡消化不了),其次i电源管了一段连续区间(也有可能只有i自己)。那么只需要枚举这一段区间就可以了。
状态转移方程dp[i]=min(dp[j]+k[i]+c[i]*(s[i]-s[j]))。其中s[i]表示电压1..i的灯泡总数。

#include<cstdio>#include<cstring>#include<algorithm>#define M(a) memset(a,0,sizeof(a))using namespace std;int min(int x,int y){    return x<y?x:y;}struct kind{    int v,sc,lc,t;    bool operator < (const kind & a) const    {        return v<a.v;    }}a[1010],k1,k2;int s[1010],dp[1010];int main(){    int i,j,k,l,m,n,p,q,x,y,z;    while (scanf("%d",&n)&&n)    {        M(a);        M(s);        for (i=1;i<=n;i++)          scanf("%d%d%d%d",&a[i].v,&a[i].sc,&a[i].lc,&a[i].t);        sort(a+1,a+n+1);        for (i=1;i<=n;i++)          s[i]=s[i-1]+a[i].t;        memset(dp,0x7f,sizeof(dp));        dp[0]=0;        for (i=1;i<=n;i++)          for (j=0;j<i;j++)            dp[i]=min(dp[i],dp[j]+a[i].sc+a[i].lc*(s[i]-s[j]));        printf("%d\n",dp[n]);    }}
0 0
原创粉丝点击