[动态规划] UVa11400 照明系统设计(线性DP)

题目

这里写图片描述

思路

1.首先有结论,每种电压的灯泡,要么全换要么不换,一种电压灯泡部分换部分不换易证是不划算的。
2.状态定义:d(i),灯泡1~i的最小开销。
3.初状态:d[0]=0,d[1]= A[1].K + A[1].L * A[1].C, d[2~n] = INF。
4.答案:d[n]
5.状态转移方程:

d ( i ) = m i n { d ( j ) + ( s [ i ] s [ j ] ) c [ i ] + k [ i ] }

  • 其中,j < i,s[i]表示前i种灯泡的总数目,也就是前缀和。
  • 表示的就是前j种先用最优方案买,然后第j+1~i种都用第i号电池。

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define _for(i,a,b) for(int i = (a); i<(b); i++)
#define _rep(i,a,b) for(int i = (a); i<=(b); i++)
using namespace std;

const int INF = 1<<30;
const int maxn = 1000+10;
int n, d[maxn], s[maxn];
struct light{
    int V,K,C,L;
    bool operator < (const struct light &rhs) const {
        return V<rhs.V;
    }
}A[maxn];

int main(){
    while(scanf("%d",&n) == 1 && n){
        _rep(i,1,n) scanf("%d%d%d%d",&A[i].V,&A[i].K,&A[i].C,&A[i].L);
        sort(A+1,A+1+n);

        memset(s,0,sizeof(s));
        _rep(i, 1, n) s[i] = s[i-1] + A[i].L;

        _rep(i,1,n) d[i] = INF;
        d[0] = 0;
        d[1] = A[1].K + A[1].L * A[1].C;
        _rep(i,2,n)
            _rep(j,0,i-1)
                d[i] = min(d[i], d[j]+(s[i] - s[j]) * A[i].C + A[i].K);

        printf("%d\n",d[n]);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/icecab/article/details/80796274