2048

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 840    Accepted Submission(s): 199

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
Hint
In the first case, we should choose all the numbers.
In the second case, all the subsequences which contain more than one number are good.
 
Source



题意:
给你n个数。从中选择一些数能构成一个序列,对于一个序列。能够进行这种操作:选择两个同样的数。将它们替换为它们的和。假设一个序列能够得到2048。那么就说这个序列式good的。问这n个数有多少个子序列是good 的。


思路:
由于每次选择同样的两个数变为他们的和,终于变为2048,所以仅仅有2的幂是有效的,其它的数(tot个)每一个都有两种状态。加或者不加,最后的种数*2^tot。
问题变为给你一些2的幂,问有多少种选取方式终于可变为2048或者2048以上。

能够联想的dp+组合。

dp[i][j]表示处理到2^i,和为[j*2^i,(j+1)*2^i )的个数,枚举选取k个2^(i+1)进行转移就可以。
算2048或者2048以上的状态时间复杂度较高,所以能够算出小于2048的状态。总方案数减去它即可了。

此题时间卡的紧,须要预处理出来逆元。组合数自己递推的时候除法变为乘法。然后还要加输入优化~

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#include <sstream>
#define maxn 100005
#define MAXN 100005
#define mod 998244353
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
using namespace std; int n,m,tot;
int mp[2050],cnt[13],p[13],ed[13];
ll ans,dp[13][2050];
ll inv[100005];
int a[12]= {2048,1024,512,256,128,64,32,16,8,4,2,1}; void scanf_(int&ret)
{
char c;
ret=0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
}
ll pow_mod(ll x,ll n)
{
ll res = 1;
while(n)
{
if(n&1) res = res * x %mod;
x = x * x %mod;
n >>= 1;
}
return res;
}
void egcd(ll a,ll b,ll &x,ll &y)
{
if (b==0)
{
x=1,y=0;
return ;
}
egcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*x;
}
void solve()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(i=0; i<=11; i++)
{
ed[i]=min(cnt[i],a[i]-1);
}
dp[0][0]=1;
ll h=1;
for(i=1; i<=ed[0]; i++)
{
h=((h*(cnt[0]-i+1))%mod)*inv[i]%mod;
dp[0][i]=h;
}
for(i=0; i<11; i++)
{
for(j=0; j<a[i]; j++)
{
if(!dp[i][j]) continue ;
h=1;
dp[i+1][j>>1]+=dp[i][j];
dp[i+1][j>>1]%=mod;
for(k=1; k<=ed[i+1]; k++)
{
if((j>>1)+k<a[i+1])
{
h=((h*(cnt[i+1]-k+1))%mod)*inv[k]%mod;
dp[i+1][(j>>1)+k]+=h*dp[i][j];
dp[i+1][(j>>1)+k]%=mod;
}
else break ;
}
}
}
ans=((pow_mod(2,n-tot)-dp[11][0]+mod)%mod)*pow_mod(2,tot);
ans%=mod;
}
int main()
{
int i,j,u,test=0;
for(i=1; i<=100000; i++)
{
ll x,y;
egcd(i,mod,x,y);
x=(x+mod)%mod;
inv[i]=x;
}
memset(mp,-1,sizeof(mp));
p[0]=1;
mp[1]=0;
for(i=1; i<=11; i++)
{
p[i]=p[i-1]*2;
mp[p[i]]=i;
}
while(1)
{
scanf_(n);
if(n==0) break ;
tot=0;
memset(cnt,0,sizeof(cnt));
for(i=1; i<=n; i++)
{
scanf_(u);
if(mp[u]!=-1) cnt[mp[u]]++;
else tot++;
}
solve();
printf("Case #%d: %I64d\n",++test,ans);
}
return 0;
}
/*
11
256 256 256 256 256 256 512 512 1024 1024 2048
*/

 

版权声明:本文博主原创文章。博客,未经同意不得转载。

hdu 4945 2048 (dp+组合的数目)的更多相关文章

  1. HDU 4945 2048 DP 组合

    思路: 这个题写了一个背包的解法,超时了.搜了下题解才发现我根本不会做. 思路参见这个: 其实我们可以这样来考虑,求补集,用全集减掉不能组成2048的集合就是答案了. 因为只要达到2048就可以了,所 ...

  2. HDU 4945 2048(DP)

    HDU 4945 2048 题目链接 题意:给定一个序列,求有多少个子序列能合成2048 思路:把2,4,8..2048这些数字拿出来考虑就能够了,其它数字不管怎样都不能參与组成.那么在这些数字基础上 ...

  3. HDU 4945 2048(dp)

    题意:给n(n<=100,000)个数,0<=a[i]<=2048 .一个好的集合要满足,集合内的数可以根据2048的合并规则合并成2048 .输出好的集合的个数%998244353 ...

  4. HDU 4945 (dp+组合数学)

    2048 Problem Description Teacher Mai is addicted to game 2048. But finally he finds it's too hard to ...

  5. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  6. hdu 4507 数位dp(求和,求平方和)

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...

  7. hdu 3709 数字dp(小思)

    http://acm.hdu.edu.cn/showproblem.php?pid=3709 Problem Description A balanced number is a non-negati ...

  8. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. hdu 4283 区间dp

    You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

随机推荐

  1. logstash+ElasticSearch+Kibana VS Splunk

    logstash+ElasticSearch+Kibana VS Splunk 最近帮磊哥移植一套开源的日志管理软件,替代Splunk. Splunk是一个功能强大的日志管理工具,它不仅可以用多种方式 ...

  2. apache +php +php curl 模块设置

    2.2 linux 下面 2.2.1 web服务器安装 1目前采用的web服务器是apache2,在ubuntu 下安装 apt-getupdate apt-get installapache2 测试 ...

  3. 后台使用oracle前台使用easyui分页机制

    前台easyui 的datagrid中设置分页属性: pagination:true,//显示分页 pagePosition:'bottom',//分页栏位置 both 上下 bottom.top p ...

  4. Java集合类汇总记录-- apache.commons4(TreeList)

    通常.Tree是Tree,List是List,两者不太可能混在一起.但apache-commons库却用tree实现了实现了List的接口,也就是TreeList类.与标准的LinkedList相比. ...

  5. Android在Context详细解释 ---- 你不知道Context

                                                                                                         ...

  6. Bootstrap网站模板

    根据一篇文章,我再想想写下,无意义,他决定收手. 或者直接做一个简单的基本的模板它 主要知识点包含栅格系统.响应式图片.导航条(固定在顶部和底部).搜索框等等 详细每一个知识点不再赘述,參考Boots ...

  7. 鸽巢原理应用-分糖果 POJ 3370 Halloween treats

    基本原理:n+1只鸽子飞回n个鸽笼至少有一个鸽笼含有不少于2只的鸽子. 很简单,应用却也很多,很巧妙,看例题: Description Every year there is the same pro ...

  8. hdu4734(数位dp)

    hdu4734 给定 a和b, 问区间[0,b]内有多少个数字的f(i) <=f(a) dp[i][s] 表示i位的数字的f<=s 所以比如如果第i+1位选择数字5之后, 那么只要剩下的i ...

  9. C++0x新特性

    我是在一个帖子上摘抄的大神语录...感谢supermegaboy大神,给了详尽的解释 下文是一篇转载的Wikipedia的译文,从语言和库双方面概述了C++0x. 右值引用与转移语义 在标准C++语言 ...

  10. 使用C++名单在文档处理和学生成绩管理系统相结合

    对于学生成绩管理系统,我并不陌生,几乎学习C人的语言.做项目会想到学生成绩管理系统,我也不例外.在研究中的一段时间C语言之后,还用C语言到学生管理系统,然后做几个链接.计数,这个系统是以前的系统上的改 ...