HDU5041-壮压DP-D

来源:互联网 发布:网络征文比赛2017 编辑:程序博客网 时间:2024/06/05 04:23

http://acm.hdu.edu.cn/showproblem.php?pid=5045
m个人n题,每个人做对的概率给定,一道题只能一个人做。他做的时候其他人休息,问你如何分配能使作对概率最大。
有一个限制条件,每时每刻做题的时候,每个人做题数差值不能大于2。
解决方法很巧妙,先让没做过题的人做,如果都做过,那么就清零。在来。。
递推的过程没什么说的,

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;const int maxn=200;double a[13][1002];double dp[1002][1050];int main(){   int t;    int m,n;    scanf("%d",&t);    for(int tt=1;tt<=t;tt++){        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)               cin>>a[i][j];        for (int i=0;i<=m;i++)            for (int j=0;j<=(1<<n)-1;j++)                dp[i][j]=-1;        dp[0][0]=0;        int peo=0;          for (int j=1;j<=m;j++)            for (int i=0;i<(1<<n);i++)                if (dp[j-1][i]!=-1)                    for (int k=1;k<=n;k++)                    {                        peo=1<<(k-1);                        if ((i&peo)==peo) continue;                        peo|=i;                        if (peo==(1<<n)-1) peo=0;                        dp[j][peo]=max(dp[j][peo],dp[j-1][i]+a[k][j]);                    }                    double ans=0;                    for(int i=0;i<(1<<n);i++){                        ans=max(ans,dp[m][i]);                    }                printf("Case #%d: %.5f\n",tt,ans);    }    return 0;}