该题以电压v,使得枚举有序化,对于每一种灯泡,怎么判断是不是要用它呢? 如何形成递推呢?
我们知道,递推就是要用到之前早已存好的值来确定当前最优解,所以我们用d[i]表示用1~i种灯泡的最小费用。
由于每种灯泡要么使用,要么被别的灯泡替代,所以d[i] = min(d[i],d[j] + (s[i]-s[j])*a[i].c + a[i].k); 其中j < i 表示前j个先用最优方案买,然后第j+1~i个都用第i号灯泡。
由于第n个灯泡电压最高,无法被别的灯泡所替代,所以必定有这个灯泡, 显然这个递推关系是严谨的 。 它可以完美的利用前面所有储存的最优方案。
细节参见代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 1000 + 10; const int INF = 2000000000; int n,d[maxn],s[maxn]; struct node{ int v,k,c,l; }a[maxn]; bool cmp(node a,node b) { return a.v < b.v; } int main() { while(~scanf("%d",&n)&&n) { 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+1+n,cmp); s[0] = 0; d[0] = 0; for(int i=1;i<=n;i++) s[i] = s[i-1] + a[i].l; for(int i=1;i<=n;i++) { d[i] = INF; for(int j=0;j<i;j++) { d[i] = min(d[i],d[j] + (s[i]-s[j])*a[i].c + a[i].k); } } printf("%d\n",d[n]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
11400 - Lighting System Design(DP)
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/46840795