【Uva 11400】Lighting System Design

Link:

Description

你要构建一个供电系统;
给你n种灯泡来构建这么一个系统;
每种灯泡有4个参数
1.灯泡的工作电压
2.灯泡的所需的电源的花费(只要买一个电源就能供这种灯泡的所有灯泡使用);
3.灯泡的单个价格
4.灯泡的所需个数;
现在,你可以把某一些灯泡换成另外一种灯泡电压要严格更高;
然后所需的灯泡个数不变,其他的都变成另外一种电压的属性;
问你最少需要花费多少钱构建这么一个供电系统;
(即买电源的钱+买灯泡的钱)

Solution

把所有的灯泡,按照电压的大小升序排;
设f[i]表示1..i这i个灯泡所需要的最小值;
则有
f[i]=min(f[j]+(sum[i]sum[j])c[i]+k[i])
j[0..i1]
sum[i];
这个转移总是连续一段地把灯泡都转换成同一个有更大的电压的灯泡;
因为,我们可以保证总是这样连续一段都转成同一个灯泡的;
比如
1 2 3 4 5
假设最后最优的答案,3变成了5,但是4没有变成5;
我们可以肯定,这种情况是不可能的;
因为这里4没有变成5,就说明,4变成5是不划算的
也就是说4这个灯泡更便宜
这么看来,3没有必要变成5;
肯定是3变成4更优;
所以得到结论,肯定都是连续地一段变成了某一个灯泡,中间不可能有间断的没变的灯泡;
反证法??

NumberOf WA

0

Reviw

这种排除中间不会有间断的,只能是连续一段转移的思维方式值得思考;

Code

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1100;
const int INF = 0x3f3f3f3f;

struct abc{
    int v,k,c,l;
};

int n,sum[N],dp[N];
abc a[N];

bool cmp(abc a,abc b){
    return a.v < b.v;
}

int main(){
    //Open();
    //Close();
    while (~scanf("%d",&n) && n){
        rep1(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,cmp);
        sum[0] = 1;
        rep1(i,1,n)
            sum[i] = sum[i-1] + a[i].l;
        ms(dp,INF);
        dp[0] = 0,dp[1] = a[1].k + a[1].c*a[1].l;
        rep1(i,2,n){
            rep1(j,0,i-1)
                dp[i] = min(dp[i],dp[j] + (sum[i]-sum[j])*a[i].c + a[i].k);
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(80)  评论(0编辑  收藏  举报