ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
来源:互联网 发布:淘宝首页源代码 编辑:程序博客网 时间:2024/05/14 06:11
题目链接
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5264
思路
题意就是n个题目,第i个题目放到第j个位置的有趣值是p[i][j]
,问你随机排列使得有趣值总和大于等于m的期望值是多少。
这个期望值很好算就是n!/cnt。
直接dfs会超时,这里用到了DP,而DP的话,如果设dp[i][j]
表示放了前i个题目,有趣值总和为j的方案数的话,会有个很大的问题,就是我们根本不知道dp[i][j]
时的排列情况,从而无法计算出dp[i+1]
时的有趣值。所以状态中必须要多一维来表示当前的排列状况,然而排列状况最多有12个位置,总不可能开个12维的数组吧…(好像可以?试试?)
最简便的方法是用状态压缩,因为每一位只有“有题目”和“没题目”两种状态,所以完全可以用一个n位的二进制数来表示,这里n<=12所以int绰绰有余。这样这个十二维的数组就瞬间压缩成一个维度了,是不是很奇妙。
于是设计状态dp[i][j]
表示排列状态为i时,有趣值和为j时的方案总数
然后排列状态的表示设计好了,怎么对这个状态进行操作呢,这就牵扯到位运算了。 (i >> k)&1
,判断第k+1位是否为1 (1 << k ) | i
,把第k+1位置为1
状态的操作也搞定了,接下来就是状态转移 dp[ i | (1 << k)][j + p[tot + 1][k+1]]+=dp[i][j] foreach (1 >> k)&1==0
转移搞定了,想一下计算顺序,i咋一看应该按照1的个数从少到多来遍历,但这个很难实现。其实可以直接从小到大直接遍历i,为什么呢,因为假设a推出了b,那么b的1的个数肯定比a多一个,换句话说,从b中删掉一个1所形成的数在这之前必须全都遍历完,而假设b删了一个1形成了a,那么肯定a<b
,所以只要增序遍历i就能满足。
j的顺序倒无所谓,因为肯定用不到当前i。
边界是dp[0][0]=1
卧槽想了这么多总算能把代码写出来了,于是我兴冲冲地写了一段代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
然后光荣TLE,(一脸卧槽)。
心灰意冷地去看了看大神们的代码,发现长得差不多?!(卧槽*2)
仔细看了下,发现了关键所在:我的count_one(i)的位置好像有点奇怪….(当时有种拍死自己的冲动)
改成这样就AC了,1200ms:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
然后又发现几个小优化。
把k和j的嵌套顺序换一下,这样可以跳过几次j的循环,500ms:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
AC代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
- ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
- ZOJ-3777 Problem Arrangement(dp状态压缩)
- zoj-3777-Problem Arrangement(状态压缩DP)
- ZOJ 题目3777 Problem Arrangement(状态压缩DP)
- ZOJ - 3777 Problem Arrangement(状态压缩dp)
- ZOJ 3777 Problem Arrangement (状态压缩 + 概率)
- zoj3777 Problem Arrangement(状态压缩dp)
- ZOJ 3777 Problem Arrangement 状压dp
- zoj 3777 Problem Arrangement (好状压dp)
- ZOJ 3777 Problem Arrangement(DP)
- 【状压DP】 ZOJ 3777 Problem Arrangement
- ZOJ 3777 - Problem Arrangement(状压DP)
- ZOJ 3777 Problem Arrangement(壮压dp)
- ZOJ 3777 Problem Arrangement (状压DP)
- zoj 3777 Problem Arrangement 【状压dp】
- ZOJ 3777Problem Arrangement(状压DP)
- ZOJ 3777Problem Arrangement-状压dp
- [00307]无穷大与NaN
- 核心机制之Java垃圾处理
- 正则【大写字母加数字,加顿号,加“至”字】
- 开涛的博客之shiro
- linux ubuntu 16.04下deb文件的安装和一些问题的解决
- ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
- PE
- 事务隔离级别
- kali Linux系统下对于python3使用pip安装库
- 用each来更改页码编号
- MediaPlayer构建音乐播放器,你所需知道的一切
- 在web.xml中classpath和classpath*的区别
- Android保存图片到图库,扫描文件到媒体库,保存图片到SD卡,可用于下载图片
- How to use epoll? A complete example in C