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)\) ...
随机推荐
- c和c++的强制类型转换
我们知道c语言中的类型转换只有一种, TYPE b = (TYPE)a; 而在c++中按照不同作用的转换类型将其细分为三个显示类型转换符号static_cast, const_cast, reinte ...
- django1.11+xadmin的搭建
1.git clone https://github.com/sshwsfc/xadmin.git或者直接下载zip包 2..在项目根目录下建一个extra_apps的包,将xadmin源码包存放在里 ...
- hdu1847Good Luck in CET-4 Everybody!(sg函数)
Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...
- lesson 20 pioneer pilots
lesson 20 Pioneer pilots driver pilot rider cyclist 骑自行车的人 介词后不加that cover + 距离 = travel 了一段距离 by su ...
- linux 学习总结---- mysql 总结
用户的创建 ---->修改 ---->删除用户 create alter drop (数据定义语言 DDL) 授权: insert update delete grant *.* revo ...
- Python全栈 Web(HTML基础语法)
原文地址: https://yq.aliyun.com/articles/632672 .............................................. ...
- leetcode-打家劫舍(动态规划)
你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定一个代表每 ...
- mvc中actionresult的返回值类型
以前一直没注意actionresult都能返回哪些类型的类型值(一直用的公司的内部工具类初始化进行返回的),今天跟大家分享一下(也是转载的别人的日志qaq). 首先我们了解一下对action的要求: ...
- HDFS essay 2 - Clarify Name Node / Checkpoint Node/ Backup Node
为什么想用英文写了?我获取知识.技术的大部分途径都是通过英文,所以按照自己的理解用英文写下来也比较容易,另外,很多term都是不能翻译的,如果要持续学习技术和知识,那就不但要习惯去阅读,听,还要写,说 ...
- ZOJ 1403 F-Safecracker
https://vjudge.net/contest/67836#problem/F "The item is locked in a Klein safe behind a paintin ...