题意:给你各个队伍对战的胜率表,然后给你要按顺序挑战的队伍,问全胜的最大胜率是多少。这道题的难点在于,获胜的时候可以选择更换队伍,也可以不更换队伍,一开始你可以选择任意队伍。
思路:这道题是一道简单的dp题目,每次只有C(m,3)种状态,每种状态表示当前队伍是哪个,我们用now数组来表示,然后每次有两种选择,更换队伍或不更换队伍。不更换队伍很明显就是now[j] *= t[j][x[i]];更换队伍的是用前一个状态中的最大值去乘t[x[i - 1]][x[i]],能理解的话基本上这道题就完了。下面给代码。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<cmath>
#include<set>
using namespace std;
#define maxn 10005
#define xx 1000000001
double t[1005][1005], now[1005];
int main() {
int m;
int a[15];
a[0] = 1;
a[1] = 1;
for (int i = 2; i <= 10; i++) {
a[i] = a[i - 1] * i;
}
while (scanf("%d", &m) != EOF) {
int r = a[m] / a[m - 3] / 6;
for (int i = 0; i < r; i++) {
for (int j = 0; j < r; j++) {
scanf("%lf", &t[i][j]);
}
}
int n;
int x[maxn];
for (int i = 0; i < r; i++) {
now[i] = 1;
}
scanf("%d", &n);
scanf("%d", &x[0]);
for (int j = 0; j < r; j++) {
now[j] *= t[j][x[0]];
}
for (int i = 1; i < n; i++) {
scanf("%d", &x[i]);
double maxnum = 0;
for (int j = 0; j < r; j++) {
maxnum = max(now[j], maxnum);
if (j != x[i - 1]) {
now[j] *= t[j][x[i]];
}
}
now[x[i - 1]] = maxnum*t[x[i - 1]][x[i]];
}
double maxnum = 0;
for (int i = 0; i < r; i++) {
maxnum = max(maxnum, now[i]);
}
printf("%.6lf\n", maxnum);
}
}