zoukankan      html  css  js  c++  java
  • UVa 11400

    题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2395

    要换灯泡的话,一定是这个种类的全换,将灯泡按电压排序,如果有灯的种类要替换成灯 (i),那么灯 (i)(c[i]*l[i]+k[i]) 一定是这段区间中最小的,最终替换成的所有灯泡的 (c[i]*l[i]+k[i]) 一定是递增的,如下图

    红线是灯泡原来的值,黑框是替换以后的值的样子

    所以我们就可以考虑 (dp),令 (dp[i]) 表示前 (i) 个灯泡的答案,转移是考虑从哪一段开始将这些灯泡都替换成灯泡 (i)

    [dp[i] = max{dp[j]+(s[j]-s[i])*c[i]+k[i]}(0<=j<i) ]

    其中 (s[i]) 表示前 (i) 个灯泡的总数量

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 1010;
    
    int n;
    int s[maxn], dp[maxn];
    
    struct Lamp{
    	int v, k, c, l;
    	
    	bool operator < (const Lamp &x) const{
    		return v < x.v;
    	}
    }a[maxn];
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	while(scanf("%d", &n) == 1 && n){
    		for(int i = 1 ; i <= n ; ++i){
    			scanf("%d%d%d%d", &a[i].v, &a[i].k, &a[i].c, &a[i].l);
    		}
    		sort(a + 1, a + 1 + n);
    		
    		s[0] = 0;
    		for(int i = 1 ; i <= n ; ++i) s[i] = s[i-1] + a[i].l; 
    		
    		memset(dp, 0x3f, sizeof(dp));
    		dp[0] = 0;
    		
    		for(int i = 1 ; i <= n ; ++i){
    			for(int j = 0 ; j < i ; ++j){
    				dp[i] = min(dp[i], dp[j] + (s[i] - s[j]) * a[i].c + a[i].k);
    			}
    		}
    		printf("%d
    ", dp[n]);
    	} 
    	return 0;
    }
    
  • 相关阅读:
    团队冲刺第四天
    团队冲刺第三天
    找1的个数
    寻找最水之王
    最优价格买书
    团队冲刺第二天
    团队冲刺第一天
    团队开发项目特点
    第一阶段冲刺站立会议报告——4
    第一阶段冲刺站立会议报告——3
  • 原文地址:https://www.cnblogs.com/tuchen/p/15043081.html
Copyright © 2011-2022 走看看