hdu 5045 Contest(状态压缩DP)

来源:互联网 发布:雄3导弹知乎 编辑:程序博客网 时间:2024/05/21 12:12

题解:我们使用一个二位数组dp[i][j]记录进行到第i个任务时,人组合为j时的最大和(这里的j我们用二进制的每位对应一个人)。


具体见代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;typedef long long ll;double s[11][1010];double dp[1010][1050];double work(int m,int n){    int k=(1<<m)-1;    for(int i=2; i<=n; i++)    {        for(int l=0,r=0; l<k; l++)        {            if(dp[i-1][l])                for(int j=0; j<m; j++)                {                    r=1<<j;                    if(l&r) continue;                    dp[i][l|r]=max(dp[i][l|r],dp[i-1][l]+s[j+1][i]);                }        }        if(dp[i-1][k])        //j==k时单独处理,相当于已经执行完一轮之后的第一个任务            for(int j=0,r=0; j<m; j++)            {                r=1<<j;                dp[i][r]=max(dp[i][r],dp[i-1][k]+s[j+1][i]);            }    }    double ans=0;    for(int i=0; i<=k; i++)        ans=max(ans,dp[n][i]);    return ans;}int main(){    int cas,m,n;    scanf("%d",&cas);    for(int ca=1; ca<=cas; ca++)    {        memset(dp,0,sizeof(dp));        scanf("%d%d",&m,&n);        for(int i=1; i<=m; i++)        {            for(int j=1; j<=n; j++)                scanf("%lf",&s[i][j]);            dp[1][1<<(i-1)]=s[i][1];        }        printf("Case #%d: %.5lf\n",ca,work(m,n));    }    return 0;}



1 0
原创粉丝点击