Uva 11400 Lighting System Design 题解

题目大意:

给定N组灯具,每组灯具包含V(灯的电压),P(电源花费),C(灯的单价),N(所需要的灯的数量)。规定低电压的灯可以换成高电压的灯,同时电源也要换。且一个电源可供无数灯运作。要求部署N组灯具的最小花费。

思路:

首先按照电压V从小到大进行排序,这样才能确定递推顺序。其次是状态转移,这里用到的是区间dp的套路即区间【L,R】由【L,i】【i+1,R】转移而来。我想过这个问题,就是能不能连续选择一段区间的问题,最初是没有证明出来的,所以也就没用这种方法。比如1,2,3。为什么不能选1,3为一组,2为一组。 仔细想想d[i]的方程表达式其意义是前i组灯具的最小花费。如果是前两组答案只能是1,2;2,2;这两种方法。如果选1,3为一组,2为一组。则2的花费肯定很大,此时就可以把2替换成3,所以上边那种解是不存在的,所以不存在漏解的情况。
所以状态转移方程:
Dp[i]=min(dp[i],(s[i]-s[j])*cost[i]+dp[j]+pow[i])

反思:

在此题中,每个阶段的决策不清晰会导致想不出状态转移方程,比如此题替换只能连续替换,决策没有很复杂。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e3+10;
const int INF=99999999;
struct terms{
    int v,power_cast,lamp_cast,num;
};
bool cmp(terms a,terms b){
    return a.v<b.v;
}
terms box[MAXN];
int dp[MAXN];
int s[MAXN];
int main()
{
    //freopen("1.txt","r",stdin);
    //freopen("2.txt","w",stdout);
    int n;
    while(scanf("%d",&n)&&n){
        memset(s,0,sizeof(s));
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d",&box[i].v,&box[i].power_cast,&box[i].lamp_cast,&box[i].num);
        }
        sort(box+1,box+1+n,cmp);
        for(int i=1;i<=n;i++){
            dp[i]=INF;
            s[i]=s[i-1]+box[i].num;
            for(int j=0;j<i;j++){
                dp[i]=min(dp[i],dp[j]+(s[i]-s[j])*box[i].lamp_cast+box[i].power_cast);
            }
        }
        printf("%d\n",dp[n]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值