UVA11400 - Lighting System Design(DP)

题意

给定n种类型灯泡,每个灯泡给出其电压v,电源花费k,每个灯的花费c和这种灯泡需求数量l(一套灯光系统总的灯泡数是每种灯泡数量之和),现在通过用电压大的灯泡替换某些电压小的灯泡来减小灯光系统总花费,求最小的花费。

题解

考虑到替换灯泡只能从低电压想高电压替换,所以最终结果一定是有灯泡被换成了高电压的。

所以可以先按照电压大小v来排序。那么动态规划中间的状态就是第i个灯泡前面的一些灯泡被替换成了第i个灯泡后,前面i个灯泡所需的最小总费用,将这个费用记作dp[i]。

那么i前面一些灯泡一定是第j(j < i)个灯泡到第i个灯泡,中间不会有漏掉的灯泡。

转移方程dp[i] = min{d[j] + (sum[i] - sum[j]) * c[i] + k[i]} sum[i]是前i个灯泡的总数量,最终的答案是dp[n]。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <vector>
#include <string.h>
#include <string>
#include <queue>
#include <set>
using namespace std;
//ios_base::sync_with_stdio(false);
//#include <bits/stdc++.h>
typedef long long ll;

const int N = 1000+5;
struct Lamp {
    int v, k, c, l;
    Lamp () {}
    Lamp (int v, int k, int c, int l): v(v), k(k), c(c), l(l){}
}L[N];
bool cmp(Lamp a, Lamp b)
{
    return a.v < b.v;
}
int dp[N], sum[N];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF && n)
    {
        for(int i = 0; i < n; i++)
        {
            int v, k, c, l;
            scanf("%d%d%d%d", &v, &k, &c, &l);
            L[i] = Lamp(v, k, c, l);
        }
        sort(L, L+n, cmp);
        for(int i = 0; i < n; i++)
        {
            sum[i] = i ? sum[i-1]+L[i].l : L[i].l;
        }
        for(int i = 0; i < n; i++)
        {
            dp[i] = L[i].k + L[i].c * sum[i]; //初始化为全部换成第i个灯泡二点价值
            for(int j = 0; j < i; j++)
            {
                dp[i] = min(dp[i], dp[j] + (sum[i] - sum[j])*L[i].c + L[i].k);
            }
        }
        printf("%d\n", dp[n-1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qihang_qihang/article/details/81157119