class="markdown_views prism-atom-one-light">
题意:现在你要设计一个电力系统,需要用到n种灯泡,每一种灯泡都有它的4个值,电压,电源费用(对于同一种灯泡,只需一个电源),每一个灯泡的费用,该种灯泡必须有的灯泡数量,本来你是想每种灯泡都用对应的电源,既是n个电源,但公司为了省钱,想将一些种类灯泡换成另一种灯泡,让他们公用一个电源,但为了保证场地灯泡足够亮,电压小的可以换成电压大的,电压大的不可以换成电压小的,例如有a,b两种灯泡,电压分别是va,vb,va
分析
线性数据结构上1动态规划
结合贪心思想:
- 每个灯要么不换要么全换,因为如果只换一部分还要给两份电源的费用(想到这里很重要)。这次是看书上分析得到的。
- dp方程的表示含义:为什么要表示为这种含义?联系dp的两个特性,最优子结构性。那么在每个部分都是最优解,假设已经得到最优解,然后再加一些元素,如何无后效性的得到加长部分的最优解呢?思考一会再看下去。
- 基本思想:从极小的子结果得到最优解(很易得),然后用已得的最优解,去比较加上另一部分后的解哪个更优。
- 如何验证最优子结构性?首先分析题目的要求:要给每个灯接一个电源,只能往电压高处接,所以要得到整体的最优解,必须要得到部分的最优解,得到接好i-1个灯的最优解,才好比较 i 的最优解。而 i 的最优解不会影响到i-1的最优解。
- 控制dp的转移方向:不能往电压低的方向接,而不回头(无后效性),所以要 把电压从小到大排序。
- 而初始状态f [ 0 ] = 0,也没有代表什么意义,只不过好转移状态。 在dp的一开始要用到f[0]与f[1]比较,要取min所以其他的 f 初始化为正无穷。
- 大致得到dp思路:含义:f[i],1—i的最优解。假设f[ j ]是最优解,让他与 j-i全接到i上比较。如果更优 ,那么,加长后f[j]就变化了。
code
不给全部的,自己补全剩下的。
f[0]=0;
sort(a+1, a+1+n, cmp);
for(int i = 1;i <= n; i++)
sum[i] = sum[i-1] + a[i].l;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
f[i] = min(f[i] , ( sum[i] - sum[j-1] ) * a[i].k + a[i].c + f[j-1] );
}
cout<< f[n] <