P4 UVA11400 Lighting System Design

发布时间 2023-08-20 09:42:14作者: Michael·F·Chen

很好的一道 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