Help Me Escape ZOJ - 3640

题意

该隐被困在有\(n\)条路的山洞里,每条路有一个困难值\(c_i\),每条路通过的时间\(t_i = \lfloor \frac{1 + \sqrt{5}}{2} * c_i ^ 2\rfloor\)

每天该隐都会被传送到任意一条路,如果他的战斗力\(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\n",dp[f]);
}
	return 0;
}
posted @ 2020-08-10 09:39  zhuzihan  阅读(43)  评论(0编辑  收藏  举报