hdu 4945 2048 (dp+组合的数目)
2048
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.
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).
4
1024 512 256 256
4
1024 1024 1024 1024
5
1024 512 512 512 1
0
Case #1: 1
Case #2: 11
Case #3: 8HintIn the first case, we should choose all the numbers.
In the second case, all the subsequences which contain more than one number are good.
能够联想的dp+组合。
#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+组合的数目)的更多相关文章
- HDU 4945 2048 DP 组合
思路: 这个题写了一个背包的解法,超时了.搜了下题解才发现我根本不会做. 思路参见这个: 其实我们可以这样来考虑,求补集,用全集减掉不能组成2048的集合就是答案了. 因为只要达到2048就可以了,所 ...
- HDU 4945 2048(DP)
HDU 4945 2048 题目链接 题意:给定一个序列,求有多少个子序列能合成2048 思路:把2,4,8..2048这些数字拿出来考虑就能够了,其它数字不管怎样都不能參与组成.那么在这些数字基础上 ...
- HDU 4945 2048(dp)
题意:给n(n<=100,000)个数,0<=a[i]<=2048 .一个好的集合要满足,集合内的数可以根据2048的合并规则合并成2048 .输出好的集合的个数%998244353 ...
- HDU 4945 (dp+组合数学)
2048 Problem Description Teacher Mai is addicted to game 2048. But finally he finds it's too hard to ...
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- hdu 4507 数位dp(求和,求平方和)
http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...
- hdu 3709 数字dp(小思)
http://acm.hdu.edu.cn/showproblem.php?pid=3709 Problem Description A balanced number is a non-negati ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 4283 区间dp
You Are the One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
随机推荐
- IIS7 配置 PHP5.5
本文环境: 操作系统:Win7(x64) 中文专业版 PHP :V5.5 首先添加IIS. 控制面板-〉程序-〉打开或关闭Windows功能 1. 勾选“Internet 信息服务” ...
- 项目中那些事|ListView中嵌套ListView问题
要在一个ListView中放入另一个ListView,也即在一个ListView的每个 item 中放入另外一个ListView.但刚开始的时候,会发现放入的子ListView会显示不完全(我这里只显 ...
- PHP实现栈(Stack)数据结构
栈(Stack),是一种特殊的后进先出线性表,其只能在一端进行插入(插入一般称为压栈.进栈或入栈)和删除(删除一般称为弹栈.退栈或出栈)操作,允许进行插入和删除操作的一端称为栈顶,另一端则称为栈底.栈 ...
- POJ 2411
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9614 Accepted: 5548 ...
- Oracle连接池
原由:许多用户可能在查询相同的数据库以获取相同的数据.在这些情况下,可以通过使应用程序共享到数据源的连接来提高应用程序的性能.否则,让每个用户打开和关闭单独的连接的开销会对应用程序性能产生不利影响.这 ...
- pygame写的弹力球
这是pygame写的弹力球 运行效果: ======================================================== 代码部分: ================= ...
- app服务器
http://heipark.iteye.com/blog/1847421http://heipark.iteye.com/blog/1847421http://wenku.baidu.com/vie ...
- Java虚拟机几个命令行参数说明
一.运行class文件 执行带main方法的class文件,Java虚拟机命令参数行为: java <CLASS文件名> 注意:CLASS文件名不要带文件后缀.class 例如: java ...
- 为VS2013添加SQLCE的支持
解决 下载SQL Server Compact Toolbox by ErikEJ并安装 打开VS2013,新建一工程,在“视图>其它窗口>SQL Server Compact Toolb ...
- android选择和裁剪图像拍摄的图像
转载请注明出处:http://blog.csdn.net/allen315410/article/details/39994913 近期从曾经的项目中扒下来一个经常使用的模块.在这里有必要记录一下的. ...