紫书经典题目了
思路就是dp
这里有个点就是一个种类的灯泡要么不换,要么全换,因为你换一半的时候需要两个电源的费用,而且你要换的话肯定往便宜的换,那肯定全换
先按电压从小到大排序
令d[i]为前i个种类的灯泡的最小费用
那怎么找呢
我们可以先让d[i]为前i个种类的全部灯泡全部转化成第i个种类的灯泡
则我们用一个j遍历1到i
而前j个种类的灯泡我们就用d[j]表示最优解的时候
让后面i-j个种类的灯泡都转化为第i号电源
再相加
方程就出来了
d[i]=min(d[i],d[j]+(sum[i]-sum[j])*a[i].c+a[i].c)
AC代码
#include <bits/stdc++.h> using namespace std; struct node { int v,k,c,l; } a[1010]; int n; int d[1010]; int sum[1010]; int main() { while(cin>>n&&n) { for(int i=1; i<=n; i++)cin>>a[i].v>>a[i].k>>a[i].c>>a[i].l; sort(a+1,a+1+n,[](node x,node y){return x.v<y.v;}); for(int i=1; i<=n; i++)sum[i]=sum[i-1]+a[i].l; for(int i=1; i<=n; i++) { d[i]=sum[i]*a[i].c+a[i].k;//先将前i个种类的全部灯泡转化成电压为a[i].v的灯泡 for(int j=1; j<i; j++) d[i]=min(d[i],d[j]+(sum[i]-sum[j])*a[i].c+a[i].k); } cout<<d[n]<<endl; } return 0; }