ZOJ-3735 Alice‘s Print Service(期望dp)

LINK

给出一个 R ∗ R R*R R∗R的矩阵 a a a

其中 a [ i ] [ j ] a[i][j] a[i][j]表示第 i i i支队伍打败第 j j j支队伍的概率

你可以随意选择一支队伍,然后开始和 m m m支 A I AI AI队伍战斗

如果你胜利了,你可以和 A I AI AI队伍交换队伍属性(交换队伍),也可以不交换

游戏开始时你可以选择任意一支队伍作为初始队伍

问获胜的最大概率。


因为 R R R最大是 120 120 120

直接定义 f [ i ] [ j ] f[i][j] f[i][j]表示已经打败了前 i i i支队伍,当前队伍是 j j j的最大获胜概率

逆推即可,设当前战斗的 A I AI AI队伍是 k k k

f [ i ] [ j ] = a [ j ] [ k ] ∗ m a x ( f [ i + 1 ] [ j ] , f [ i + 1 ] [ k ] f[i][j]=a[j][k]*max(f[i+1][j],f[i+1][k] f[i][j]=a[j][k]∗max(f[i+1][j],f[i+1][k]

这样就轻松解决了…

这题正着推也没关系…无所谓了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+120;
double a[230][230],f[10009][230];
int n,m,ai[maxn];
signed main()
{
	while( cin >> n )
	{
		n = n*(n-1)*(n-2)/6;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%lf",&a[i][j]);
		cin >> m;
		for(int i=1;i<=m;i++)	scanf("%d",&ai[i]),ai[i]++;
		for(int i=1;i<=n;i++)	f[m+1][i] = 1;
		
		for(int i=m;i>=0;i--)
		for(int j=1;j<=n;j++)
			f[i][j] = a[j][ai[i]]*max( f[i+1][j],f[i+1][ai[i]] );
		double ans = 0;
		for(int i=1;i<=n;i++)	ans = max( ans,f[1][i] );
		printf("%.6lf\n",ans);
	}
}
上一篇:ehcarts 折线图数据出现叠加?


下一篇:刷题-力扣-230. 二叉搜索树中第K小的元素