[2017浙工大之江学院决赛 E] qwb和李主席(折半枚举,二分)

题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=4

题意:把一个数组拆成两部分,使得两个集合分别的和的差的绝对值最小。

做过类似的,用01背包,求sum/2容量下的最大价值,这样可以拆成两个集合,并且符合题意。

但是这题浮点数,而且物品价值1e9,不能背包了。

n<=36,也不能直接枚举。

可以把n个数拆成两部分,先枚举一部分的组合情况,把和求出来,再枚举另一部分,枚举到一个和x后在第一部分的和里二分地枚举一个和y,使得x+y最接近sum/2。然后每次更新两部分的和A=x+y, B=sum-A,更新ret=min(abs(A-B))即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 66;
 5 int n, na, nb;
 6 double v[maxn], a[maxn], b[maxn];
 7 double s[1<<20], sum;
 8
 9 double gao(double val) {
10     int lo = 1, hi = (1 << nb), ret = -1;
11     while(lo <= hi) {
12         int mid = (lo + hi) >> 1;
13         if((s[mid] + val) * 2.0 >= sum) {
14             ret = mid;
15             hi = mid - 1;
16         }
17         else lo = mid + 1;
18     }
19     double A = s[ret] + val , B = sum - A;
20     return abs(A - B);
21 }
22
23 int main() {
24     // freopen("in", "r", stdin);
25     while(~scanf("%d",&n)) {
26         na = nb = 0;
27         sum = .0;
28         memset(s, 0, sizeof(s));
29         for(int i = 1; i <= n; i++) {
30             scanf("%lf", &v[i]);
31             sum += v[i];
32             if(i <= n / 2) a[na++] = v[i];
33             else b[nb++] = v[i];
34         }
35         for(int i = 0; i < (1 << na); i++) {
36             for(int j = 0; j < na; j++) {
37                 if(i & (1 << j)) s[i+1] += a[j];
38             }
39         }
40         sort(s+1, s+(1<<na)+1);
41         double ret = 1e18;
42         for(int i = 0; i < (1 << nb); i++) {
43             double tmp = .0;
44             for(int j = 0; j < nb; j++) {
45                 if(i & (1 << j)) tmp += b[j];
46             }
47             // double A = tmp + *lower_bound(s+1, s+(1<<na)+1, sum/2.0-tmp);
48             // double B = sum - A;
49             ret = min(ret, gao(tmp));
50         }
51         printf("%.2f\n", ret);
52     }
53     return 0;
54 }
时间: 2024-11-01 10:31:02

[2017浙工大之江学院决赛 E] qwb和李主席(折半枚举,二分)的相关文章

[2017浙工大之江学院决赛 L] qwb与整数对(离线,筛)

题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=11 这题不会,看了柠檬巨的题解才知道可以筛出来. 枚举a.b,然后求下m最小能是多少,可以满足原式为整数.可以用(a*b)-(a*a+b*b)%(a*b)求.然后在m的基础上算上a*b的倍数再更新到对应case上即可. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int

[2017浙工大之江学院决赛 M] qwb与二叉树(记忆化搜索,卡特兰数)

题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=12 题意:中文题面. 假如不限定叶子数的话,问题就是求二叉树形态数,可以每次枚举节点数,以后来的节点为根,左右子树的形态数做乘法原理得到,就是卡特兰数. 这里多限定了叶子数,其实没有什么区别,在枚举的时候,左右子树再分别统计一下不同叶子数的情况就行. 1 #include <bits/stdc++.h> 2 using namespace std

qwb和李主席

qwb和李主席 Time Limit: 4 Sec  Memory Limit: 128 MB Description qwb和李主席打算平分一堆宝藏,他们想确保分配公平,可惜他们都太懒了,你能帮助他们嘛? Input 输入包含多组测试数据,处理到文件结束. 每组测试数据的第一行是一个正整数N(0 <= N <=36 )表示物品的总个数.. 接下来输入N个浮点数(最多精确到分),表示每个物品的价值V(0<V<=1e9). Output 对于每组测试数据,输出能够使qwb和李主席各自

2017年浙江工业大学之江学院程序设计竞赛决赛 I: qwb VS 去污棒(可持久化Trie+离线)

问题 I: qwb VS 去污棒 时间限制: 2 Sec  内存限制: 256 MB 提交: 74  解决: 26 [提交][状态][讨论版] 题目描述 qwb表白学姐失败后,郁郁寡欢,整天坐在太阳底下赏月.在外人看来,他每天自言自语,其实他在和自己的影子“去污棒”聊天. 去污棒和qwb互相出题考验对方,去污棒问了qwb这样一个问题: 现已知一个有n个正整数的序列a[1],a[2]...a[n],接下来有m个操作 操作一共有两种: 1.在序列末尾添加一个数x. 2.查询suf[p] xor x的

[2017年第0届浙江工业大学之江学院程序设计竞赛决赛 I] qwb VS 去污棒(并查集,按秩合并,最小生成树,LCA)

题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=8 题意:中文题面. 手动画一下会发现所求边必然存在于最大生成树上,那么就可以首先构造一棵最大生成树. 问题转化成一棵树上求两个点之间的链上的最短边,用倍增lca就可以做了,但是我不会. 于是可以考虑建树时的操作,在求最大生成树的时候按秩合并,即集合大的根要做集合小的根的父亲,这样连一条有向边,保证路径上的所有边没有变化,并且能够维持整棵树高不会超过log(

之江学院程序设计竞赛

Description qwb遇到了一个问题:将分数a/b化为小数后,小数点后第n位的数字是多少? 做了那么多题,我已经不指望你能够帮上他了... Input 多组测试数据,处理到文件结束.(测试数据<=100000组) 每组测试例包含三个整数a,b,n,相邻两个数之间用单个空格隔开,其中0 <= a <1e9,0 < b < 1e9,1 <= n < 1e9. Output 对于每组数据,输出a/b的第n位数,占一行. Sample Input 1 2 1 1

2017广东工业大学程序设计竞赛决赛-tmk买礼物

tmk买礼物 Description 今天是校赛的日子,为了庆祝这么喜庆的日子,TMK打算买些礼物给女票LSH庆祝一下. TMK进入了雪梨超市,然后刚踏入的一瞬间,店主就对TMK说:“恭喜你成为了本店第2147483647位顾客,本店在搞一个活动,对本店第2147483647位顾客进行赠送活动.你先看看你有多少钱?” TMK一摸口袋,发现只有n个硬币,每个硬币的价值为a[i]. 然后店主继续说:“现在你用你的钱凑一些数,如果你的钱能凑成[0,x]里面所有的数,那么你将会免费获得该店价值x元的代金

2017广东工业大学程序设计竞赛决赛 G 等凹数字

题意: Description 定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字.现在问你[L,R]中有多少等凹数字呢? Input 第一行一个整数T,表示数据的组数. 接下来T行每行俩个数字L和R,(1<=L<=R<=1e18) Output 输出一个整数,

2017浙江工业大学-校赛决赛 竹之书

Description 由于某些原因菲莉丝拿到了贤者之石,所以好像变得很厉害了好像变得很厉害的菲莉丝想要炼成幻想乡,其中有一个原料是稗田一族对幻想乡历史的记录.现在菲莉丝拿到了一个被某只魔粘性精神体加密过的的卷轴.密文通过原文和一个正整数key加密形成,而key和密文又有一定关联.现给出密文,求key值 已知密文s和key值关系如下已知密文s是一串正整数s1,s2,s3--sn,A为s中所有元素的和,B为s中所有元素的积,key为B mod A 数据范围si,A在(0,1e17]范围内0<n<