uva11400--Lighting System Design DP

本文介绍了一道经典的动态规划问题——UVA-11400,主要内容包括题目的背景、解题思路以及详细的代码实现。通过分析题目要求,提出了解决方案,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

https://cn.vjudge.net/problem/UVA-11400

题目大意:

给出n种灯泡的单价(C)、需求量(L)、电压(V)与电压的价格(K)(同种灯泡可共用一个电源)
低压灯泡可用相等数量的高压灯泡替换
求最小花费

解题思路:

首先,我们可以发现如果要用高亚灯泡替代一种低压灯泡,一定是低压灯泡被全部替代时最优。因为如果换一部分的话,不会减少电源花费,那就只会在灯泡花费上省钱,但既然可以在灯泡上省钱,那不是换得越多省的越多么?而且,全部换完,还可以剩下一个电源的钱。
那么我们就可以定义状态f[i]表示:前i种灯泡的最小花费。
这样如果我们用sum[i]表示灯泡数量的前缀和的话,就不难得出一下状态转移方程式:f[i] = min(f[j]+(sum[i]-sum[j])*C[i]+K[i])
值得注意的是:为什么我们可以只替换连续的一段就得到最后的正确答案呢?这样做不会少了很多情况吗?比如说只替换前面的某种灯泡,或者我间断性的替换灯泡,会不会更优呢?
其实:这种情况是不存在的,因为

  1. 如果我要用当前灯泡i去替换前面的某种灯泡k,只可能是使用k并没有一起使用i优。
  2. 我不用当前i去替换灯泡j∈(k,i),只可能是i并没有j优。

但,如果j比i优,i比k优,那么j就比k优,所以我们就不需要用i去替换k了,因为在那之前j已经替换了k并将最优值保存到了f[j]中。

所以,不连续的替换是不存在的,当i要替换k时,一定会保证i比∀j∈(k,i)都要优,否则就不会替换k

此外,为了保证i一定能替换i前面的灯泡,所以这里我们要先按照电压(V)从小到大排序

Code:

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
int n, f[MAXN], sum[MAXN];
struct Node{
    int v, k, c, l;
    bool operator < (const Node &x) const{
        return v < x.v;
    }
}p[MAXN];
int main(){
    while(scanf("%d",&n), n){
        for(int i = 1; i <= n; ++ i)
            scanf("%d%d%d%d",&p[i].v,&p[i].k,&p[i].c,&p[i].l);
        sort(p+1, p+n+1);
        for(int i = 1; i <= n; ++ i){
            sum[i] = sum[i-1]+p[i].l;
            f[i] = sum[i]*p[i].c+p[i].k;
            for(int j = 1; j < i; ++ j)
                f[i] = min(f[i], f[j]+(sum[i]-sum[j])*p[i].c+p[i].k);
        }
        printf("%d\n",f[n]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值