分析:首先我们需要明白一个问题,就是每种电压的灯泡要么就是全部替换,要么全部不替换,为什么呢?因为如果只替换一半,那两种电源都需要,不划算,从另一个方面来说,既然转化一半会比原来小,那为什么不全部转换呢?接着根据题意我们应该把灯泡按照电压从小到大排序。然后我们令dp[i]表示1~i的最小开销,令sum[i]表示前i种灯泡的数量,则dp[i]=min(dp[j]+(sum[i]-sum[j])*p[i].c+p[i].k),表示前j个先用最优方案,然后j+1~i换成第i号电源。有人会问这样是否会漏解,比如第i个,只替换我们1,3,5这样子的,但是这种情况是不存在的,为什么呢?设i<j<k,如果i替换成k,而j没有替换,说明j是更优的,那i为什么不转移到j呢?
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "algorithm" 6 using namespace std; 7 const int maxn=1000+10; 8 const int INF=1<<30; 9 struct Node{ 10 int v,k,c,l; 11 }; 12 Node p[maxn]; 13 int n; 14 bool cmp(Node a,Node b){ 15 return a.v<b.v; 16 } 17 int sum[maxn]; 18 int dp[maxn]; 19 int main() 20 { 21 while(cin>>n) 22 { 23 if(n==0) break; 24 for(int i=1;i<=n;i++){ 25 cin>>p[i].v>>p[i].k>>p[i].c>>p[i].l; 26 } 27 sort(p+1,p+1+n,cmp); 28 for(int i=1;i<=n;i++) 29 sum[i]=sum[i-1]+p[i].l; 30 dp[0]=0; 31 for(int i=1;i<=n;i++){ 32 dp[i]=INF; 33 for(int j=0;j<=i;j++){ 34 dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j])*p[i].c+p[i].k); 35 } 36 } 37 cout<<dp[n]<<endl; 38 } 39 return 0; 40 }
原文:http://www.cnblogs.com/wolf940509/p/7257934.html