山再高,往上爬,总能登顶;
路再长,走下去,定能到达。
信息宝典-系统可靠性
题目描述
太空梯工程作为一个系统,由n个部件串联而成,只要有一个部件故障,系统就不能正常运行,为提高系统的可靠性,每一部件都装有备用件,一旦原部件故障,备用件就自动进入系统。显然备用件越多,系统可靠性越高,但费用也越大,那么在一定总费用限制下,系统的最高可靠性等于多少?
给定一些系统备用件的单价Ck,以及当用Mk个此备用件时部件的正常工作概率Pk(Mk),总费用上限C。求系统可能的最高可靠性。
输入
第一行: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])
输出
输出系统可能的最大可靠性,保留 4位有效数字。
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
n<=10,C<=100,1<=Ci<=20
输入为不定项输入
题目大意
一节太空梯分为好几截,每一截都是相互独立的。要求所有截同时正常工作的时候,才算是系统正常工作。
为了使系统可靠,我们采用增加备用零件的方式,来提高系统可靠性。
每增加一个配件,这一截运行正常的概率就会更新到对应的概率
比如,添加2个一号件,4个二号件。该题样例中运行正常的概率是0.7×0.9=0.63,同时花费2×3+5×4=26
思路分析
如果采用dfs的话很显然复杂度过于庞大,TLE是在所难免的。所以得改用动态规划,很显然这是每一个样例选多少的问题,其实可以看做完全揹包来做,考虑每一个样例选多少个。
先初始化一下dp的第0层,都是1.0。接着,从每一行开始,都要考虑我能在当前的money下能最多买几个零件。然后考虑这些零件我要买几个。这样我们就会得到在一截对应的money下的最优选择。
解题代码(Python)
save=[]#概率
val=[]#代价
dp=[]
ans=0
#初始化同态规划空间
for i in range(25):
temp=[]
for j in range(105):
temp.append(0.0);
dp.append(temp)
#输入n,c
n,c=map(int,input().split())
#处理输入的 价值 概率
for i in range(n):
temp=input().split()
val.append(int(temp[0]))
save.append(list(map(float,temp[1:])))
#动态规划初始化
for i in range(c+1):
dp[0][i]=1.0
#完全揹包(二维形式)
for i in range(1,n+1):
for j in range(c+1):
for k in range(min(len(save[i-1])-1,j//val[i-1])+1):
dp[i][j]=max(dp[i][j],dp[i-1][j-val[i-1]*k]*save[i-1][k])
#寻求最大值
for i in range(c+1):
ans=max(ans,dp[n][i])
#输出结果
print("%.4f"%ans)
总结
这题的思路很简单,主要的问题就是在于如何动态规划,和处理不定输入。
因为不定输入的原因,博主偷个懒直接用Python做了,其实C++是一样的思路。
这题的核心思想还是完全揹包,只不过这里的揹包需要用二维的dp记录。
有问题请及时指出,并争取在第一时间回复,感谢支持!
By-轮月