SP11469 SUBSET-Balanced Cow Subsets meet-in-the-middle+状压

正解:折半搜索

解题报告:

传送门!

这题我开始看到的时候贼开心地就把这题的代码直接粘过来辣

然后就T辣,,,仔细思考一下,为什么呢?

因为会枚举到很多相同的状态

举个eg

20

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

那就考虑怎么改进?

因为想到,它枚举到了很多相同的状态

那我们就可以直接存某个状态能否达成,开个桶记录

然后最后for枚举状态地统计就好了

(然后还有一个就是,记得开int,longlong会超时,不要问我怎么知道的TT

 

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define rg register
#define ll int
#define rp(i,x,y) for(rg ll i=x;i<=y;++i)

const ll N=20+10,M=2000000+10;
ll n,m,a[N],cnt,as;
bool vis[M];
map<ll,ll>mp;
vector<ll>dist[M<<1];

il ll read()
{
    rg char ch=getchar();rg ll x=0;rg bool y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=getchar();
    if(ch=='-')ch=getchar(),y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
    return y?x:-x;
}
void dfs1(ll num,ll tot,ll stat)
{
    if(num>m){if(mp.find(tot)==mp.end())mp[tot]=++cnt;dist[mp[tot]].push_back(stat);return;}
    dfs1(num+1,tot,stat);
    dfs1(num+1,tot+a[num],stat|(1<<(num-1)));
    dfs1(num+1,tot-a[num],stat|(1<<(num-1)));
}
void dfs2(ll num,ll tot,ll stat)
{
    if(num>n)
    {if(mp.find(tot)==mp.end())return;ll id=mp[tot],sz=dist[id].size();rp(i,0,sz-1)vis[dist[id][i]|stat]=1;return;}
    dfs2(num+1,tot,stat);
    dfs2(num+1,tot+a[num],stat|(1<<(num-1)));
    dfs2(num+1,tot-a[num],stat|(1<<(num-1)));
}
int main()
{
    n=read();m=n>>1;rp(i,1,n)cin>>a[i];
    dfs1(1,0,0);dfs2(m+1,0,0);rp(i,1,(1<<n))as+=vis[i];printf("%d\n",as);return 0;
}
View Code

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值