很好的一道 DP 题。
首先按照电压排序。
然后考虑 \(dp[i]\) 表示前 \(i\) 盏灯的最小花费,则应该有 \(dp[i]=min(dp[j]+(s[i]-s[j])*c[i]+k[i])\),其中 \(s[i]\) 表示前 \(i\) 盏灯的总需求数。
为什么可以这样子直接用前缀,而不用考虑 "跳着选" 呢?是因为如果跳着选,就说明有一盏灯在一盏更优灯的前面,那么先前在这盏更优灯的时候就应该已经更新过了。反证证毕。
const int N=1005;
int n,f[N],s[N];
struct Lamp{
int v,k,c,l;
}lamp[N];
signed main(){
//freopen();
//freopen();
IOS
//int T;
while(cin>>n){
if(!n) break;
for(int i=1;i<=n;++i)
cin>>lamp[i].v>>lamp[i].k>>lamp[i].c>>lamp[i].l;
sort(lamp+1,lamp+1+n,[&](Lamp A,Lamp B)
{ return A.v<B.v;});
for(int i=1;i<=n;++i) s[i]=s[i-1]+lamp[i].l;
memset(f,0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<=n;++i)
for(int j=0;j<i;++j)
f[i]=Min(f[i],f[j]+(s[i]-s[j])*lamp[i].c+lamp[i].k);
cout<<f[n]<<'\n';
}
return 0;
}
· EOF
标签:int,Lamp,System,lamp,Lighting,UVA11400,Design,dp From: https://www.cnblogs.com/mfc007/p/17643623.html