题意
该隐被困在有(n)条路的山洞里,每条路有一个困难值(c_i),每条路通过的时间(t_i = lfloor frac{1 + sqrt{5}}{2} * c_i ^ 2 floor)天
每天该隐都会被传送到任意一条路,如果他的战斗力(f > c_i),他就能通过该路,否则不能。
没能通过的路会将该隐的战斗力增加(c_i)
给定(n)条路的(c_i),给定(n)和初始战斗力(f),求该隐逃离山洞的期望天数。
分析
考虑DP
是否可以对天数DP?显然我们需要同时记录天数和战斗力,这是二维的DP,并且每一维都是
1w级别的,不行。
然后我们发现天数不重要,战斗力比较重要,我们考虑(dp[i])表示战斗力为(i)所期望逃脱的天数,
(Ans = dp[f])
[dp[j] = frac {sum_{i = 1}^{n} t_i*[j>c_i] sum_{i=1}^{n}dp[j + c_i]*[j leq c_i]}{n}
]
(j + c_i)的范围在2w以内。
记忆化(dfs)和(dp)都可以。
[code]
#include<bits/stdc++.h>
using namespace std;
#define ld long double
ld dp[20050];
int n,f,c[110],t[110];
int main(){
while(scanf("%d%d",&n,&f) != EOF){
for(int i = 1; i <= n; ++ i) { scanf("%d",&c[i]); t[i] = ((1.0 + sqrt(5.0)) / 2.0 * c[i] * c[i]); }
for(int i = 20010; i >= f; -- i){
dp[i] = 0;
for(int j = 1; j <= n; ++ j)
if(i > c[j]) dp[i] += t[j];
else dp[i] += (1 + dp[i + c[j]]);
dp[i] /= n;
}
printf("%.3Lf
",dp[f]);
}
return 0;
}