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 ...
随机推荐
- sleep和wait的区别
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制.wait指线程处于进入等待状态,形象地说明为“等待使用C ...
- hdu1255(线段树——矩形面积交)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意:求N个矩形中,求被覆盖至少俩次的面积和 分析:覆盖两次即col[rt]>=2就好.一 ...
- 【剑指offer】旋转数组的最小值
採用二分查找的策略,重点要考虑一些边界情况:旋转了0元素.即输入的是一个升序排列的数组.仅仅包括一个数字的数组.有非常多反复数字的数组等. AC代码: #include<stdio.h> ...
- poj3126解题报告
题意:简单的说就是:有一个人门牌号是一个四位数的整数,并且还是一个素数,现在他想要换成另外一个四位数且是素数的门牌号,而且,每次都只能更换这个四位数的一个位置的数 ,也就是每换一次都只改变一个数字,而 ...
- Kruskal(克鲁斯卡尔)
设有一个有n个顶点的连通网N={V,E},最初先构造一个只有n个顶点, 没有边的非 连通图 T={V, E}, 图中每个顶点自成一个连通分量. 当在E中选到一条具有最小权值的边时,若该边的两个顶点落在 ...
- 静态方法使用bean
java类中的代码 public class BidMsgUtil { private static Logger log = Logger.getLogger(BidMsgUtil.class); ...
- android贴士Toast
转载请注明出处:http://blog.csdn.net/droyon/article/details/42009015 我们可以用androd提供toast控制,但在使用过程中,给我们发了很多Toa ...
- 学派Delphi方法(推荐)——————————【Badboy】
Delphi是一个新的可视化编程环境, 提供了一种方便.快捷的Windows使用顺序开发工具. 它使用了MicrosoftWindows图形用户界面的很多先进特性和设计思想. 本文就给读者引见学Del ...
- BZOJ-2115-Xor-WC2011
叙述性说明 分析 我把文库里的粘了过来. 仅仅知道点1到点N的一条路径和图中若干个环.就能通过异或,表示成全部路径.那么.须要多少环才干保证必然能表示成全部路径呢?事实上.并不须要非常多, 由于一些环 ...
- 10令人惊叹的模型的影响HTML5应用程序及源代码
HTML5已经越来越流行起来了.尤其是移动互联网的发展,更是带动了HTML5的迅猛发展,我们也是时候学习HTML5了,以防到时候落伍.今天给大家介绍10款效果惊艳的HTML5应用.方便大家学习,也将应 ...