本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
题目链接:http://codeforces.com/contest/1185/problem/G1
题目大意是说,给你n首歌曲的时间和类型。给你一个总的时间T。让你从n首歌曲中选择任意几首歌曲。使之时间和等于总的时间,求满足的条件的次数。不可以连续选择同一种类型的歌曲。
dfs暴力超时。一看到这种题就想暴力。555
事后才知道是状压dp。
看到题目数据范围,自己就应该想到的。n小于15。这不就是用二进制的每一位来表示这首歌是否选择了吗。
我们定义一个dpmask][las]的dp数组。
其中mask是表示每首歌的选择情况。las是表示最后选择的歌曲是哪一个类别。
dp[mask][las]表示这样的选择方案有多少种。
很明显了。dp的推导公式应该为:
dp[mask ^ (1 << j)][g[j]] += dp[mask][las];
如果,这个数组正确推导。然后,在遍历数组一次,同时求出所有选择方案的时间和等于T 的次数和。
初始值&