HDU-5045 Contest(状压DP)

来源:互联网 发布:云计算软件 编辑:程序博客网 时间:2024/05/20 17:42

HDU-5045 Contest

一、题目原文
In the ACM International Collegiate Programming Contest, each team consist of three students. And the teams are given 5 hours to solve between 8 and 12 programming problems.

On Mars, there is programming contest, too. Each team consist of N students. The teams are given M hours to solve M programming problems. Each team can use only one computer, but they can’t cooperate to solve a problem. At the beginning of the ith hour, they will get the ith programming problem. They must choose a student to solve this problem and others go out to have a rest. The chosen student will spend an hour time to program this problem. At the end of this hour, he must submit his program. This program is then run on test data and can’t modify any more.

Now, you have to help a team to find a strategy to maximize the expected number of correctly solved problems.

For each problem, each student has a certain probability that correct solve. If the ith student solve the jth problem, the probability of correct solve is Pij .

At any time, the different between any two students’ programming time is not more than 1 hour. For example, if there are 3 students and there are 5 problems. The strategy {1,2,3,1,2}, {1,3,2,2,3} or {2,1,3,3,1} are all legal. But {1,1,3,2,3},{3,1,3,1,2} and {1,2,3,1,1} are all illegal.

You should find a strategy to maximize the expected number of correctly solved problems, if you have know all probability

Input
The first line of the input is T (1 ≤ T ≤ 20), which stands for the number of test cases you need to solve.

The first line of each case contains two integers N ,M (1 ≤ N ≤ 10,1 ≤ M ≤ 1000),denoting the number of students and programming problem, respectively.

The next N lines, each lines contains M real numbers between 0 and 1 , the jth number in the ith line is Pij .

Output
For each test case, print a line “Case #t: ”(without quotes, t means the index of the test case) at the beginning. Then a single real number means the maximal expected number of correctly solved problems if this team follow the best strategy, to five digits after the decimal point. Look at the output for sample input for details.

Sample Input
1
2 3
0.6 0.3 0.4
0.3 0.7 0.9

Sample Output
Case #1: 2.20000

Source
2014 ACM/ICPC Asia Regional Shanghai Online
二、题目大意
有m个任务,每个任务从n个人中选一个人去完成,第i个人完成第j个任务的概率是盘p[i][j], 在任意时刻分配给每个人的任务数不得比分配其他任何人的任务数大于一(可以等于),问:完成任务的最大期望是多少?
三、解题思路
首先,对于分布

i 1 2 3 4 … P(x=i) p1 p2 p3 p4 …

p(x==i)表示第i次成功的概率,其期望为E=sigma(pi);

根据题目要求,不难想到,在任意时刻,分配给某一个的任务数只能比其他人大1,或者相等。因此,若令p=min(某人的任务数),所有人的任务数只有p,p+1两种情况,等于p的视为0,p+1视为1,每一时刻的分配状态可用一个n位的二进制数表示。因此用dp[i][j]表示j状态下,解决前i个问题可以获得最大期望,状态转移为:dp[i][j]=max{dp[i][j-(1< < k)]}(k为j对应二进制位为1的位)。值得注意的是,(1 < < n)-1(分配数全部为p+1)的状态与0(分配数全部为0)的状态相同,因此还有一条转移为dp[i][0]=dp[i][(1 < < n ) - 1 ]。
四 、代码

    #include<iostream>    #include<cstdio>    #include<cstring>    #include<map>    #include<list>    #include<algorithm>    #include<vector>    #include<string>    #include<fstream>    //#pragma comment(linker,"/STACK:1024000000,1024000000")    using namespace std;    const int N=1e5+5;    int n,m;    double dp[1005][(1<<10)];    double p[11][1005];    int main()    {        int t;        scanf("%d",&t);        int tt=0;        while(t--)        {            scanf("%d %d",&n,&m);            for(int i=1;i<=n;i++)                for(int j=1;j<=m;j++)            {                scanf("%lf",&p[i][j]);            }            for(int i=0;i<=1000;i++)                for(int j=0;j<(1<<10);j++)                dp[i][j]=-10000;                dp[0][0]=0.0;            for(int i=1;i<=m;i++){                for(int j=0;j<(1<<n);j++)                {                    for(int k=0;k<n;k++)                        if(j&(1<<k)) dp[i][j]=max(dp[i][j],dp[i-1][j-(1<<k)]+p[k+1][i]);                }                dp[i][0]=dp[i][(1<<n)-1];            }            double ans=0.0;            for(int i=0;i<(1<<n);i++)                ans=max(ans,dp[m][i]);//,cout<<dp[1][i]<<endl;            printf("Case #%d: %.5lf\n",++tt,ans);        }       return 0;    }
0 0
原创粉丝点击