题意:有一个照明系统需要用到n种灯,每种灯的电压为V,电源费用K,每个灯泡费用为C,需要该灯的数量为L。注意到,电压相同的灯泡只需要共享一个对应的电源即可,还有电压低的灯泡可以被电压高的灯泡替代。为了节约成本,你将设计一种系统,使之最便宜。
分析:由于只能用大电压换小电压的,所以先对每种灯泡按照电压大小排序,每种灯泡有两种状态:全换与全不换,先求出前i种灯泡的数量总和,用dp[i]表示前i种灯泡的最优方案
可得状态转移方程:
dp[i] = min(dp[i],dp[j]+(sum[i]-sum[j])*a[i].c+a[i].k);
代码:
#include <map> #include <set> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <iomanip> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define ll long long #define mod 1000000007 #define mem(a) memset(a,0,sizeof(a)) using namespace std; const int maxn = 1000 + 5 , inf = 0x3f3f3f3f ; struct light{ int v,k,c,l; bool operator < (const light &temp )const{ return v<temp.v; } }; light a[maxn]; int sum[maxn]; int dp[maxn]; int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n; while(scanf("%d",&n)!=EOF&&n){ mem(sum),mem(a);mem(dp); 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+n+1); for(int i = 1 ; i <= n ; i ++ ) sum[i] = a[i].l + sum[i-1]; for(int i = 1 ; i <= n ; i ++ ){ dp[i] = sum[i]*a[i].c+a[i].k;//初始化 for(int j = 1 ; j < i ; j++ ){ dp[i] = min(dp[i],dp[j]+(sum[i]-sum[j])*a[i].c+a[i].k); } } cout<<dp[n]<<endl; } }