在任意时刻,任意两个人的答题时间不能超过1小时。换句话说,就是每n道题要n个人轮流一遍(n是人数)。
状态压缩dp,dp[i][j] 表示答前i道题答题人员分配为 j 这个状态时的最大期望。
#include <iostream> #include<stdio.h> using namespace std; int n,m; double p[20][1010],dp[1010][1500],ans; void init() { for(int i = 0;i <= m;i++) for(int j = 0;j <= (1<<n);j++) dp[i][j] = -1; dp[0][0] = 0; } void work() { init(); for(int i = 0;i < m;i++) //枚举第几题 { for(int j = 0;j < 1<<n;j++)//枚举上一个状态 { if(dp[i][j]<0)continue; for(int k = 0;k < n;k++) //枚举当前第几人答题 { if(((j>>k)&1)==0) //当前这个人没有答题 { int tmp = j|(1<<k); if(tmp == (1<<n)-1) tmp = 0; if(dp[i][j]+p[k][i+1] > dp[i+1][tmp]) { dp[i+1][tmp] = dp[i][j]+p[k][i+1]; } } } } } } int main() { int t; scanf("%d",&t); int cas = 1; while(t--) { scanf("%d %d",&n,&m); for(int i = 0;i < n;i++) //人编号从0开始,题目编号从1开始 for(int j = 1;j <= m;j++) scanf("%lf",&p[i][j]); ans = 0; work(); for(int i = 0;i < (1<<n);i++) if(dp[m][i] > ans) ans = dp[m][i]; printf("Case #%d: %.5lf\n",cas++,ans); } return 0; }