1 条题解
-
0
解题思路分析
-
数据预处理:
- 对于每个对手球队,将投手按胜率从高到低排序,并仅保留前5名(因为状态压缩只能处理5个投手)。
- 预处理后,每个球队对应一个长度为5的投手列表,列表中的投手按胜率降序排列。
-
动态规划状态设计:
- 使用五维数组
dp[a][b][c][d][e]
表示当前状态,其中a, b, c, d, e
分别表示最近的5场比赛中选择的投手在预处理列表中的位置(1-5)。 - 状态转移时,通过深度优先搜索(DFS)枚举所有可能的投手选择组合,确保每个投手的休息时间符合规则。
- 使用五维数组
-
状态转移与更新:
- 每天处理一场比赛,根据前一天的状态计算当天的可能状态。
- 通过DFS生成所有合法的投手选择组合,并更新DP数组中的最大值。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node { int val,pos; }em[110][110]; bool cmp(node a,node b) { return a.val>b.val; } int dp[2][6][6][6][6]; int T,t,n,m,g,fight[300],vis[110],num[10],from,to,day,ans; void dfs(int pos) { if(pos==-1) { dp[to][num[1]][num[2]][num[3]][num[4]]=max(dp[to][num[1]][num[2]][num[3]][num[4]], dp[from][num[0]][num[1]][num[2]][num[3]]+em[fight[day]][num[4]].val); return; } for(num[4-pos]=1;num[4-pos]<=5;num[4-pos]++) { if(vis[em[fight[day-pos]][num[4-pos]].pos]>0) continue; vis[em[fight[day-pos]][num[4-pos]].pos]++; dfs(pos-1); vis[em[fight[day-pos]][num[4-pos]].pos]--; } } int main() { int i,j,k,a,b,c,d; scanf("%d",&T); for(t=1;t<=T;t++) { scanf("%d%d%d",&n,&m,&g); memset(em,0,sizeof(em)); memset(fight,0,sizeof(fight)); for(i=1;i<=m;i++) for(j=1;j<=n;j++) { scanf("%d",&em[i][j]); em[i][j].pos=j; } for(i=1;i<=m;i++) sort(em[i]+1,em[i]+1+n,cmp); n=min(n,5); for(i=11;i<=g+20;i++) scanf("%d",&fight[i]); memset(dp,0,sizeof(dp)); vis[0]=-100; for(day=11;day<=g+20;day++) { if(day&1) from=0; else from=1; to=1^from; memset(dp[to],0,sizeof(dp[to])); dfs(4); } ans=0; for(a=0;a<=5;a++) for(b=0;b<=5;b++) for(c=0;c<=5;c++) for(d=0;d<=5;d++) ans=max(ans,dp[to][a][b][c][d]); printf("%.2f\n",0.01*ans); } }
-
- 1
信息
- ID
- 2393
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者