期望值最大的dp,转移有环
开始在想强连通分量缩点之后,块内高斯消元+拓扑图dp。
但是高斯消元没有max的转移。
所以用了处理有环最大值的方法:floyd
总结一下:
处理转移有环的方法:
最短路(单源 floyd)主要是求max/min
高斯消元 主要是求期望。
强连通分量缩点 主要是题内有明显提示或强连通分量内部有特殊性质。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1e9
#define eps 1e-10
#define md
#define N 110
using namespace std;
double w[N],f[N][N],g[N][N];
int a[N][N];
int main()
{
int n,m,S;
double p;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%lf",&w[i]);
scanf("%d%lf",&S,&p);
n++;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
g[i][j]=-inf;
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y]=1; g[x][y]=w[y]*p;
}
w[n]=0;
for (int i=1;i<=n;i++) g[i][n]=0;
for (int t=1;t<=50;t++,p*=p)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
f[i][j]=-inf;
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
f[i][j]=max(f[i][j],g[i][k]+g[k][j]*p);
memcpy(g,f,sizeof(f));
//printf("%.2lf : %.2lf %.2lf %.2lf\n",p,g[1][2],g[1][3],g[1][4]);
}
double ans=-inf;
for (int i=1;i<=n;i++)
ans=max(ans,f[S][i]);
printf("%.1lf\n",ans+w[S]);
return 0;
}