您的位置:首页 > 理论基础 > 计算机网络

HDU 5045 Contest (2014上海网络赛)

2014-09-28 20:36 435 查看
这个题是一个DP。 有状态压缩的问题。 以前只是听说过 状态压缩的DP 还没有真正练过。 今天还好把这个题弄明白了

其中有一个条件就是不论什么时候。 任何两个人的做题时间之差不能超过2. 那个这个条件的另一个意思也就是说。 必须所有人都做一遍之后 再所有人再做一遍 这样循环

用 d【i】【j】 表示 前 i个题 都有 哪几个人做了。j是用二进制表示。 比如 i为2 j为 101000 就表示 前两个题 被 第一个人 和第三个人 做了的概率。

当所有人都做了一遍的时候 即 11111 这样的时候 j 再转为 0 再重新 找人。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <fstream>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cmath>
#include <iomanip>
typedef long long LL;
typedef unsigned long long LLU;
const double PI=acos(-1.0);
using namespace std;
#define MAXN 1200
double peo[15][MAXN];
double d[MAXN][MAXN];
int main (){
    int t;
    int kase = 0;
    scanf("%d",&t);
    while(t--){
        int pe,con;
        scanf("%d%d",&pe,&con);
        for(int i = 0; i < pe; i++)
            for(int j = 0; j < con; j++)
                scanf("%lf",&peo[i][j]);
        for(int i = 0; i < MAXN; i++){
            for(int j = 0; j < MAXN; j++)
                d[i][j] = -1;
        }
        d[0][0] = 0;
        for(int i = 0; i < con; i++){
            for(int j = 0; j < (1 << pe); j++){
                int s;
                if(d[i][j] < 0)
                    continue;
                for(int k = 0; k < pe; k++){
                    if(!((1 << k) & j)){ // 第k个人没做过题
                        s = ((1 << k) | j);
                        if(s == (1 << pe) - 1)
                            s = 0;          // 所有人都做过了一遍 重新做
                        d[i+1][s] = max(d[i+1][s], d[i][j] + peo[k][i]);
    //                    printf("%lf\n",d[i+1][s]);
                    }
                }
            }
        }
        double ans = 0.0;
        printf("Case #%d: ",++kase);
        for(int i = 0; i < (1 << pe); i++)
            ans = max(ans, d[con][i]);
        printf("%.5lf\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: