题意:
有一个吸血鬼被困了,有n条路可以逃出去,每条路有一个难度c[],他初始的战斗力是f,对于第i条路,若f > c[i]他花t[i]天就能出去,否则,他就停留一天,同时战斗力增加c[i]然后再选一条路走出去,他走每条路的概率是相同的。问他逃出去的天数的期望。
设dp[i]表示在战斗力为i时逃出去的期望值,那么可推出状态方程
dp[i] = 1/n * t[j](c[j] > i),dp[i] = 1/n * (1+dp[ i+c[j] ] )( c[j] <= i)。
需要注意的是终态的确定。当f > Max时,这时的期望值为总时间的平均值便是终态了,但是i + c[j]有可能大于Max+1,(也就是f最大为Max)所以终态应该是Max*2。初始化时就忘乘2了。
还有就是t[i]是整数。
自己总是不知道到底让dp表示什么好。。。。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<cstring>
using namespace std;
double dp[1000010];
int b[110];
double a=(1+sqrt(5))*0.5;
int main()
{
int n,f;
while(~scanf("%d %d",&n,&f))
{
int Max=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&b[i]);
Max=max(Max,b[i]);
}
memset(dp,0,sizeof(dp));
for(int i=2*Max; i>=f; i--)
{
dp[i]=0;
for(int j=1; j<=n; j++)
{
if(i>b[j])dp[i]+=(int)(a*b[j]*b[j]);
else dp[i]+=(1+dp[i+b[j]]);
}
dp[i]/=n;
}
printf("%.3lf\n",dp[f]);
}
return 0;
}
递归方法,觉得还是这个方法好理解
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#define ll long long
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int MAXN=1000010;
const double op=(1.0+sqrt(5))/2;
double dp[MAXN];
bool vis[MAXN];
int n;
int c[110];
double dfs(int u)
{
if(vis[u])
return dp[u];
vis[u]=1;
dp[u]=0;
for(int i=0;i<n;i++)
{
if(c[i]<u)
{
double temp=op*c[i]*c[i]*1.0;
int t=(int)temp;
dp[u]+=1.0*t/n;
}
else
dp[u]+=(1+dfs(u+c[i]))/n*1.0;
}
return dp[u];
}
int main()
{
int f,i;
while(scanf("%d%d",&n,&f)==2)
{
for(i=0;i<n;i++)
scanf("%d",&c[i]);
memset(vis,0,sizeof(vis));
double ans=dfs(f);
printf("%.3f\n",ans);
}
return 0;
}