zoukankan      html  css  js  c++  java
  • [CSP校内集训]building(折半搜索)

    题意

    (n)个东西,每个可以选择不取、取价值(a_i)、取价值(b_i),求恰好凑出价值(x)的方案数(,(nleq 25,a_i,b_i,xleq 10^{13}))

    思路

    这种看起来很简单暴力的题只用考虑爆搜就完了,但是直接爆搜是(O(3^n))会飞

    折半搜索,分成将(n)分成两部分,前一半搜出来的方案数开个map存起来,后一半搜出来的方案数乘上前面即可,复杂度优化至(O(3^{n/2}logx))

    这样做相当于将原来一个个加答案变成一次加一堆

    Code

    #include<bits/stdc++.h>
    #define N 26
    #define lowbit(x) ((x)&(-(x)))
    #define Min(x,y) ((x)<(y)?(x):(y))
    #define Max(x,y) ((x)>(y)?(x):(y))
    using namespace std;
    typedef long long ll;
    int n,half;
    ll x,a[N],b[N],ans;
    map<ll,ll> mp;//状态的出现次数 
    
    template <class T>
    void read(T &x)
    {
    	char c; int sign=1;
    	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
    }
    void DFS(int step,ll now)
    {
    	if(step==half+1) {++mp[now];return;}
    	if(now>x) return;
    	DFS(step+1,now);
    	DFS(step+1,now+a[step]);
    	DFS(step+1,now+b[step]);
    }
    void dfs(int step,ll now)
    {
    	if(step==n+1)
    	{
    		if(now<=x) ans+=mp[x-now];
    		return; 
    	}
    	if(now>x) return;
    	dfs(step+1,now);
    	dfs(step+1,now+a[step]);
    	dfs(step+1,now+b[step]);
    }
    int main()
    {
    	freopen("building.in","r",stdin);
    	freopen("building.out","w",stdout);
    	read(n);read(x);
    	for(int i=1;i<=n;++i)
    	{
    		read(a[i]);
    		ll c=a[i],cnt=0;
    		while(c)
    		{
    			++cnt;
    			c-=lowbit(c);
    		}
    		b[i]=(1LL<<cnt);
    	}
    	if(n==1)
    	{
    		cout<<(0==x)+(a[1]==x)+(b[1]==x)<<endl;
    		return 0;
    	}
    	half=n/2;
    	DFS(1,0);
    	dfs(half+1,0);
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    MySQL锁
    mysql服务性能优化—my.cnf配置说明详解
    springmvc请求参数获取的几种方法
    Linux mysql 添加远程连接
    Linux 操作 mysql
    Linux 安装 mysql 转 http://www.cnblogs.com/fnlingnzb-learner/p/5830622.html
    linux 下 安装nginx
    dubbo 实战总结
    分布式事务的几种方式
    精巧好用的DelayQueue 转
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11804901.html
Copyright © 2011-2022 走看看