题目链接:
https://vjudge.net/problem/UVA-11400
题意:
题解:
按照电压从小到大排序,一种灯泡要么不换,要么全换; 否则依旧是两个电源,没省钱。
因为可能电压高的费用小,肯定全换,并且还可以剩下一个电源费用
还可能电压高的费用大,那也要全换,跑一跑,取最小值,因为可能电源费用省的更多那。
dp[i]:=前i个的最小费用
dp[i] = min(dp[i],dp[j]+(s[i]-s[j])*a[i].c+a[i].k);
一定要排序之后再求前缀和…
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 int n,dp[maxn]; 19 int s[maxn]; 20 21 struct node{ 22 int v,k,c,l; 23 bool operator<(const node& rhs)const{ 24 return v < rhs.v; 25 } 26 }a[maxn]; 27 28 int main(){ 29 while(scanf("%d",&n) && n){ 30 s[0] = 0; 31 for(int i=1; i<=n; i++) 32 scanf("%d%d%d%d",&a[i].v,&a[i].k,&a[i].c,&a[i].l); 33 34 sort(a+1,a+1+n); 35 36 for(int i=1; i<=n; i++) 37 s[i] = s[i-1]+a[i].l; 38 dp[0] = 0; 39 40 for(int i=1; i<=n; i++){ 41 dp[i] = dp[i-1]+ a[i].l*a[i].c+a[i].k; 42 for(int j=0; j<i; j++){ 43 dp[i] = min(dp[i],dp[j]+(s[i]-s[j])*a[i].c+a[i].k); 44 } 45 } 46 47 cout << dp[n] << endl; 48 49 } 50 51 return 0; 52 }