HDU 5045

http://acm.hdu.edu.cn/showproblem.php?pid=5045

题意:n个学生m道题,一个n*m的矩阵代表第n个学生解第m题AC的概率,任意两学生做题数差距不能大于1,问AC所有题目概率的最大值

由于限制条件,所以一定是以n个学生为单位,一轮一轮的做题,直到做m题为止,这样题目就转化为了一个状态压缩dp,当状态为(1<<n)-1的时候清空状态

dp[i][j]表示AC 前i道题目状态为j的最大值

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <algorithm>
using namespace std ;
typedef __int64 ll ;
double dp[1005][1050] ;//
double p[15][1005] ;

int n,m ;

int main()
{
    int T ;
    scanf("%d",&T) ;
    for(int cas=1 ;cas<=T ;cas++)
    {
        scanf("%d%d",&n,&m) ;
        for(int i=0 ;i<n ;i++)
        {
            for(int j=0 ;j<m ;j++)
                scanf("%lf",&p[i][j]) ;
        }
        for(int i=0 ;i<1005 ;i++)
            for(int j=0 ;j<1050 ;j++)
                dp[i][j]=-1.0 ;
        dp[0][0]=0.0 ;
        int sm=(1<<n)-1 ;
        for(int i=0 ;i<m ;i++)
        {
            for(int s=0 ;s<=sm ;s++)
            {
                if(dp[i][s]<0.0)continue ;
                int st=0 ;
                for(int j=0 ;j<n ;j++)
                {
                    if(!((1<<j)&s))
                    {
                        st=(1<<j)|s ;
                        if(st==sm)st=0 ;
                        dp[i+1][st]=max(dp[i+1][st],dp[i][s]+p[j][i]) ;
                    }
                }
            }
        }
        double ans=0.0 ;
        for(int i=0 ;i<=sm ;i++)
            ans=max(ans,dp[m][i]) ;
        printf("Case #%d: %.5lf\n",cas,ans) ;
    }
    return 0 ;
}

时间: 2024-08-04 07:30:38

HDU 5045的相关文章

HDU 5045 5047 5050 5053(上海网络赛E,F,I,L)

HDU 5045 5047 5050 5053 太菜了,名额差点没保住,吓尿..赶紧开刷树链抛分 5045:状压DP,压缩10个人,由于两个人不能差2以上,所以可以用01表示 5047:推推公式即可,每次交线多4条 5050:求GCD,用java大叔即可 5053:签到题 代码: 5045: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N

HDU 5045 状压DP 上海网赛

比赛的时候想的是把n个n个的题目进行状压 但这样不能讲究顺序,当时精神面貌也不好,真是挫死了 其实此题的另一个角度就是一个n个数的排列,如果我对n个人进行状压,外面套一个按题目循序渐进的大循环,那么,在当前做第i个题目,前i-1个题目已经做完,然后做完的人的状态为j, j可能是1110 1101 1011什么的(假设已经做了三道题),因为我这样就可以只管状态而不管顺序了,我只取这种状态下的最大值,他究竟是怎么个顺序排列我不用管 到此...好像问题就没有什么问题了,这种做法重复 m/n次最后把剩余

HDU 5045 DP+状压

2014 ACM/ICPC Asia Regional Shanghai Online 给出N个人做M道题的正确率,每道题只能由一个人做出,并且当所有人都做出来且仅做出一道题时,做过题的人才可以继续做题,求最大期望. 一共只有10个人,状压存储每个人是否已经做出题目,如果都作出则状态清0: #include "stdio.h" #include "string.h" double Max(double a,double b) { if (a<b) return

hdu 5045 费用流

滚动建图,最大费用流(每次只有就10个点的二分图).复杂度,m/n*(n^2)(n<=10),今年网络赛唯一网络流题,被队友状压DP秒了....难道网络流要逐渐退出历史舞台???.... #include<iostream> //78ms #include<cstdio> #include<queue> using namespace std; const double inf =0x3f3f3f3f; const int maxv=50,maxe=500; in

HDU 5045 费用流求最大权

点击打开链接 题意:有n个人和m到题目,每个人做对的概率以矩阵形式给出,问如何分配才可以使做对的概率最大,有一个限制条件是做到目前为止每两个人的做题数量差距不能超过1,也就是前n道题目,必须一人做一个 思路:网上都是dp多一点,用网络流也可以,不过麻烦很多,可是本弱是一点dp都不会的选手啊,只能用网络流了,对于那个限制条件,我们可以以前n道题建一次图,然后再来n个,不过就直接建完就可以了,然后我们要求的是什么呢,很明显是最大权,而最大费用最大流刚好可以解决,这里面的费用流有两种方法,用spfa找

状态压缩dp poj 3254 hdu5045

近来感觉状态压缩dp的强大性(灵活利用了二进制运算很关键)...于是做了俩提来看看..毕竟队友是专业的dp,我只是管中窥豹下而已..日后有机会再与之玩耍玩耍...ps:如果上天再给我一次机会,当年我愿意选择状态dp而不是网络流(只针对目前比赛出题潮流) 经典问题,不相邻/禁点方案数问题.poj3254 #include<iostream> #include<cstdio> using namespace std; int n,m; int dp[5000][15]; int yu[

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往