系统可靠性 (简单)
TimeLimit:1000MS Memory Limit:65536K
Total Submit:1 Accepted:1
Description
一个系统由若干部件串联而成,只要有一个部件故障,系统就不能正常运行,为提高系统的可靠性,每一部件都装有备用件,一旦原部件故障,备用件就自动进入系统。显然备用件越多,系统可靠性越高,但费用也越大,那么在一定总费用限制下,系统的最高可靠性等于多少?
给定一些系统备用件的单价Ck,以及当用Mk个此备用件时部件的正常工作概率Pk(Mk),总费用上限C。求系统可能的最高可靠性。
Input
第一行:n C
第二行:C1 P1(0) P1(1) …P1(X1) (0<=X1<=[C/Ck])
…
第 n 行:Cn Pn(0) Pn(1) … Pn(Xn) (0<=Xn<=[C/Cn])
Output
系统可能的最高可靠性。
Sample Input
2 20
3 0.6 0.65 0.7 0.75 0.8 0.85 0.9
5 0.7 0.75 0.8 0.8 0.9 0.95
Sample Output
0.6375
Hint
DP
资源分配类型
附:题解+代码
program systemcode;
var
n,money:longint;
a:array [0..100,-1..100] of real;//用a[i,j]表示第i项备用件花了j*i元能取得的最高可靠性,特别地,a[i,-1]表示这项备用件的费用,a[i,0]表示不花钱或者买不起一个第i项备用件所得到的最高可靠性
f:array [0..100,0..100] of real;//用f[i,j]表示前i项备用件用j元钱能取得的最高可靠性
procedure init;
var
i,j:longint;
begin
readln(n,money);
for i:=1 to n do
begin
read(a[i,-1]);
for j:=0 to (money div trunc(a[i,-1])) do read(a[i,j]);
readln;
end;
end;
function max(x,y:real):real;
begin
if x>y then exit(x) else exit(y);
end;
procedure main;
var
i,j,k,tx:longint;
temp:real;
begin
temp:=1;
for i:=0 to money do
begin
tx:=i div trunc(a[1,-1]);//这里是对应买了几个第1项备用件
if tx>0 then
begin
f[1,i]:=a[1,tx];//买得起则对应标号
continue;
end
else
begin
f[1,i]:=a[1,0]; //买不起则对应不花钱的情况
continue;
end;
end;
for i:=1 to n do
begin
temp:=a[i,0]*temp;
f[i,0]:=temp;
end;
for i:=2 to n do//i=1时我们已经人工算出了每个情况的最高可靠性
begin
for j:=0 to money do
begin
tx:=j div trunc(a[i,-1]);//当前的钱能买几个第i项备用件
for k:=0 to tx do f[i,j]:=max(f[i-1,j-k*trunc(a[i,-1])]*a[i,k],f[i,j]);//这些钱我们可以一点都不用在买第i项备用件,或者全用来买第i项备用件,或者买k个第i项备用件
//DP方程:f[i,j]=max{f[i-1,j-k*trunc(a[i,-1])]*a[i,k],f[i,j]},这里f[i,j]主要是用来被覆盖更新的,在初始情况下,它一定会被f[i-1,j-k*trunc(a[i,-1])]替换,此后通过打擂台更新f[i,j]
end;
end;
end;
begin
assign(input,'systemcode.in'); reset(input);
assign(output,'systemcode.out'); rewrite(output);
init;
main;
writeln(f[n,money]:0:4);
close(input); close(output);
end.