题意:
n个人m个对手给出每个人能战胜每个敌人的概率,现在有g个比赛,每个人赛完后要休息4天(可重复用),求能获得胜利的最大期望个数。
分析:
因为只有每个人5天就能用一次,所以对于每个人来说,只有得分前5的会被使用上,所以后4维状态只需要5^4,进行状态转移
dp[i][j][k][l][p]表示第i场比赛,前一天为j,两天为k,三天为l,四天为p,的最大得分,只和i-1状态有关用滚动数组。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct node{ int id,v; }win[110][110]; int dp[2][6][6][6][6],n,m,g,d[255]; bool cmp(node x,node y){ return x.v>y.v; } int cal(int i,int j){ if(i==0||j==0)return 0; return win[i][j].id; } int t; int main() { scanf("%d", &t); while (t--) { int ans = 0; scanf("%d%d%d", &n, &m, &g); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &win[i][j].v); win[i][j].id = j; } sort(win[i] + 1, win[i] + 1 + n, cmp); } g += 10; int i,j,k,y,l,x; for (i = 1; i <= g; i++) scanf("%d", &d[i]); memset(dp[0], 0, sizeof(dp[0])); int now=0; for (i = 1; i <= g; i++) { now^=1; memset(dp[now], 0, sizeof(dp[now])); if (d[i]) { for (y = 1; y <= 5; y++) { for (j = 0; j <= 5; j++) { if (i > 1 && cal(d[i], y) == cal(d[i - 1], j)) continue; for (k = 0; k <= 5; k++) { if (i > 2 && cal(d[i], y) == cal(d[i - 2], k)) continue; for (l = 0; l <= 5; l++) { if (i > 3 && cal(d[i], y) == cal(d[i - 3], l)) continue; for (x = 0; x <= 5; x++) { if (i > 4 && cal(d[i], y) == cal(d[i - 4], x)) continue; dp[now][y][j][k][l] = max(dp[now][y][j][k][l], dp[now^1][j][k][l][x] + win[d[i]][y].v); ans = max(ans, dp[now][y][j][k][l]); } } } } } } else { for (j = 0; j <= 5; j++) { for (k = 0; k <= 5; k++) { for (l = 0; l <= 5; l++) { for (x = 0; x <= 5; x++) { dp[now][0][j][k][l] = max(dp[now][0][j][k][l], dp[now^1][j][k][l][x]); ans = max(ans, dp[now][0][j][k][l]); } } } } } } printf("%.2lf\n", ans * 1.0 / 100); } return 0; }
时间: 2024-10-22 04:39:05