POJ3977:Subset——题解(三分+折半搜索)
http://poj.org/problem?id=3977
题目大意:有一堆数,取出一些数,记他们和的绝对值为w,取的个数为n,求在w最小的情况下,n最小,并输出w,n。
————————————————————
两天时间,终于搞下。
这题显然我们唯一能做到的只有暴力,但是2^35显然不可取……
但是显然我们折半搜索的话复杂度只有2^18左右所以没问题。
将数分成两堆,每一堆暴力求出所有情况并记录。
然后枚举第一堆,三分第二堆求解即可。
(为什么三分呢?因为绝对值啊,一定最优解是在函数的最低点,所以是单峰函数)
……思路挺简单是不是,但是注意以下几点:
1.n不为零,这点需要特判。
2.三分很容易写跪,具体怎么做看我代码。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll INF=;
inline ll abss(ll a){
if(a<)return -a;
return a;
}
struct num{
ll w;
ll n;
}mp1[],mp2[];
ll a[];
int cnt1=,cnt2=;;
bool in[];
void dfs(int n,int k,bool t){
memset(in,,sizeof(in));
if(!t){
mp1[++cnt1].w=mp1[cnt1].n=;
}
for(int res=;res<=((<<k)-);res++){
int cnt=;
int lz=res;
while(lz){
in[++cnt]=lz-lz/*;
lz/=;
}
ll sum=,num=;
for(int i=;i<=cnt;i++){
int j=i;
if(t)j+=n/;
if(in[i]){
sum+=a[j];
num++;
}
}
if(!t){
mp1[++cnt1].w=sum;
mp1[cnt1].n=num;
}else{
mp2[++cnt2].w=sum;
mp2[cnt2].n=num;
}
}
return;
}
bool cmp(num c,num d){
if(c.w<d.w)return ;
if(c.w>d.w)return ;
if(c.n<d.n)return ;
return ;
}
ll ans,cnt;
void sanfen(int l,int r,num k){
if(r-l<=){
ll t1=abss(k.w+mp2[l].w);
ll t2=abss(k.w+mp2[r].w);
ll t3=abss(k.w+mp2[(l+r)/].w);
ll c1=mp2[l].n+k.n;
ll c2=mp2[r].n+k.n;
ll c3=mp2[(l+r)/].n+k.n;
ll t,c;
if(t1>t2||(t1==t2&&c1>c2)){
t=t2;c=c2;
}else{
t=t1;c=c1;
}
if(t>t3||(t==t3&&c>c3)){
t=t3;c=c3;
}
if(ans>t||(ans==t&&cnt>c)){
ans=t;cnt=c;
}
return;
}
int mid1=(r+*l)/;
int mid2=(l+*r)/;
ll t1=abss(k.w+mp2[mid1].w);
ll t2=abss(k.w+mp2[mid2].w);
if(t1<t2||(t1==t2&&mp2[mid1].n+k.n<mp2[mid2].n+k.n)){
sanfen(l,mid2-,k);
}else{
sanfen(mid1+,r,k);
}
return;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF&&n){
cnt1=,cnt2=;
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
dfs(n,n/,);
dfs(n,n-n/,);
sort(mp2+,mp2+cnt2+,cmp);
//for(int i=1;i<=cnt1;i++)printf("1 %lld %lld\n",mp1[i].w,mp1[i].n);
//for(int i=1;i<=cnt2;i++)printf("2 %lld %lld\n",mp2[i].w,mp2[i].n);
ans=INF;cnt=INF;
for(int i=;i<=cnt1;i++){
sanfen(,cnt2,mp1[i]);
if(i>){
if(ans>abss(mp1[i].w)||(ans==abss(mp1[i].w)&&cnt>mp1[i].n)){
ans=abss(mp1[i].w);cnt=mp1[i].n;
}
}
}
printf("%lld %lld\n",ans,cnt);
}
return ;
}
POJ3977:Subset——题解(三分+折半搜索)的更多相关文章
- [题解](折半搜索)luogu_P4799_BZOJ_4800世界冰球锦标赛
抄的题解 以及参考:https://www.cnblogs.com/ZAGER/p/9827160.html 2^40爆搜过不了,考虑折半搜索,难点在于合并左右的答案,因为有可能答案同时载左右两边,我 ...
- [题解](折半搜索/高斯消元枚举自由元)BZOJ_1770_Lights
状压,时间空间都不行,如果每次搜索一半就可以省下很多空间,用map记下每种状态的答案,最后再把两次的答案合并 然而正解是高斯消元解异或方程组,最后搜索自由元 #include<iostream& ...
- 洛谷3067 BZOJ 2679题解(折半搜索)
传送门 BZOJ传送门(权限题) 看到n小于20,就可以想到搜索 所有的数要么在集合a中,要么在集合b中,要么都不在 可是3^n复杂度会炸,我们考虑优化 可以利用折半搜索,将前面一半的所有可能情况与后 ...
- Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索
Codeforces Round #297 (Div. 2)E. Anya and Cubes Time Limit: 2 Sec Memory Limit: 512 MBSubmit: xxx ...
- [NOIP10.4模拟赛]2.y题解--折半搜索+状压计数
题目链接: 咕 闲扯: 这题暴力分似乎挺多,但是一些奇奇怪怪的细节没注意RE了,还是太菜了 分析: 首先我们考虑最naiive的状压DP ,\(f[u][v][state]\)表示u开头,v结尾是否存 ...
- 折半搜索+Hash表+状态压缩 | [Usaco2012 Open]Balanced Cow Subsets | BZOJ 2679 | Luogu SP11469
题面:SP11469 SUBSET - Balanced Cow Subsets 题解: 对于任意一个数,它要么属于集合A,要么属于集合B,要么不选它.对应以上三种情况设置三个系数1.-1.0,于是将 ...
- 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
[LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...
- 【BZOJ4800】[CEOI2015 Day2]世界冰球锦标赛 (折半搜索)
[CEOI2015 Day2]世界冰球锦标赛 题目描述 译自 CEOI2015 Day2 T1「Ice Hockey World Championship」 今年的世界冰球锦标赛在捷克举行.\(Bob ...
- 【BZOJ 2679】[Usaco2012 Open]Balanced Cow Subsets(折半搜索+双指针)
[Usaco2012 Open]Balanced Cow Subsets 题目描述 给出\(N(1≤N≤20)\)个数\(M(i) (1 <= M(i) <= 100,000,000)\) ...
随机推荐
- NB-IOT连接移动onenet平台流程
1. 先创建账号,然后创建产品 2. 创建设备,用AT+CGSN和AT+CIMI查询NB-IOT的IMEI和IMSI填写上去. 3. 创建好的设备.
- MySQL高级-查询截取分析
一.如何分析 1.观察.至少跑1天,看看生产的慢SQL情况. 2.开启慢查询日志,设置阙值比如超过5秒钟的就是慢SQL,并将它抓取出来. 3.explain + 慢SQL分析 4.show profi ...
- 用CRF做命名实体识别(二)
用CRF做命名实体识别(一) 用CRF做命名实体识别(三) 一. 摘要 本文是对上文用CRF做命名实体识别(一)做一次升级.多添加了5个特征(分别是词性,词语边界,人名,地名,组织名指示词),另外还修 ...
- Qt 独立运行时伴随CMD命令窗口
用Qt写了一个小软件,在把程序release后,打包分装后,发现程序运行的时候会伴随cmd命令窗口,可把我愁怀了 不过功夫不负有心人,在老师和我网友的帮助下,终于搞完了 CONFIG:指定工程配置和编 ...
- Linearize an sRGB texture in Photoshop
From:https://forum.unity.com/threads/bug-with-bypass-srgb-sampling.282469/
- solidity python 签名和验证
注意,以太坊智能合约里面采用的是公钥非紧凑类型 def gen_secrets_pair(): """ 得到公钥和私钥 :return: ""&quo ...
- 5.安装hbase
下载安装包并解压设置hbase环境变量配置hbase-site.xml启动hbase检测hbase启动情况测试hbase shell 下载安装包并解压 https://mirrors.tuna.tsi ...
- Python中的global和nonlocal
在Python中,一个变量的scope范围从小到大分成4部分:Local Scope(也可以看成是当前函数形成的scope),Enclosing Scope(简单来说,就是外层函数形成的scope), ...
- “Hello World!”团队第三周召开的第五次会议
一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码地址 一.会议时间 2017年10月31日 11:45-12:17 二.会议地点: ...
- Android开发随笔5
昨天: 对界面的进一步设计补充 可以在界面之间的跳转 研究了对图标等的操作 今天: 实现对库的相关操作 学习视视频内容‘ 复习java的一些知识.