首页 > 代码库 > 2014多校8(1001)hdu4945(dp+组合数计数+求逆元)

2014多校8(1001)hdu4945(dp+组合数计数+求逆元)

2048

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 566    Accepted Submission(s): 129


Problem Description
Teacher Mai is addicted to game 2048. But finally he finds it‘s too hard to get 2048. So he wants to change the rule:

You are given some numbers. Every time you can choose two numbers of the same value from them and merge these two numbers into their sum. And these two numbers disappear meanwhile.
  
If we can get 2048 from a set of numbers with this operation, Teacher Mai think this multiset is good.

You have n numbers, A1,...,An. Teacher Mai ask you how many subsequences of A are good.

The number can be very large, just output the number modulo 998244353.
 

Input
There are multiple test cases, terminated by a line "0".

For each test case, the first line contains an integer n (1<=n<=10^5), the next line contains n integers ai (0<=ai<=2048).
 

Output
For each test case, output one line "Case #k: ans", where k is the case number counting from 1, ans is the number module 998244353.
 

Sample Input
4 1024 512 256 256 4 1024 1024 1024 1024 5 1024 512 512 512 1 0
 

Sample Output
Case #1: 1 Case #2: 11 Case #3: 8

题意:给出n个数字(0~2048),求能够用这些数字组成的集合中能够找出若干个数的和为2048的集合数量

思路:首先要保证能组成2048,那么这些数只能形如2的x次方,所以可以将不是2的幂的数先给删掉,最后求总的数量的时候再算上就好了

然后现在就只剩下形如2的x次方的数了,很容易看出,如果一个集合的总和大于或等于2048,那么一定可以在这个集合中找出一堆数去组成2048

这样我们就可以求反面,即求出总和小于2048的集合数量,可以用dp[i][j]表示选完了所有的从2的0次方到2的i次方的数,总和在[j*2的i次方,(j+1)*2的i次方)范围的集合数量,

转移方程为dp[i][j]=dp[i][j]+(dp[i-1][(j-k)*2]+dp[i-1][(j-k)*2+1])*C(n,k),其中n为2的i次方的数一共有多少个,k为当前要选的2的i次方数的数量,显然最后答案为total-dp[11][0],

其中total为所有形如2的x次方的数能够组成的集合数量

最后算上之前剔除的数即可

<script src="https://code.csdn.net/snippets/451135.js" type="text/javascript"></script>