http://acm.hdu.edu.cn/showproblem.php?pid=5045
给出N个人做M道题的正确率,每道题只能由一个人做出,并且当所有人都做出来且仅做出一道题时,做过题的人才可以继续做题,求最大期望。
n最大值是10,想到用状压
状压dp
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <queue> #include <vector> #include<set> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d%d",&x,&y) #define clr0(x) memset(x,0,sizeof(x)) typedef long long LL; double dp[1005][1<<10]; int n,m; double p[12][1005]; int main() { int T; scanf("%d",&T); int iCase = 0; while(T--){ iCase++; RD2(n,m); for(int i = 0;i < n;i++){ for(int j = 0;j < m;++j){ scanf("%lf",&p[i][j]); } } double ans = 0; int sum = 1<<n; for(int i = 0;i <= m;++i) for(int j = 0;j < sum;++j) dp[i][j] = -1; dp[0][0] = 0; for(int i = 0;i < m;++i) for(int j = 0;j < sum;++j){ if(0 > dp[i][j]) continue; for(int k = 0;k < n;++k){ if( ((1<<k) & j) == 0){ int st = (1<<k) | j; if(st + 1 == sum) st = 0; dp[i+1][st] = max(dp[i+1][st],dp[i][j] + p[k][i]); } } } for(int i = 0;i < sum;++i){ ans = max(ans,dp[m][i]); } printf("Case #%d: %.5lf\n",iCase,ans); } return 0; }