题意 : 给出一个数 n ,要求你用 k 个二的幂来组成这个数,要求输出这 k 个二的幂的指数,如果有多解情况则优先输出最大指数最小的那一个且要求按字典序输出,不存在则输出 No 分析 :  先来说一个结论对于一个二的幂例如 2^n 我们可以将其拆成 2^(n-1) + 2^(n-1) 那么对于题目所给出的数 n 我们可以先将其拆成二进制形式,如果当前二进制表示法中 1 的个数已经超过 k 则应该是输出 No 也就是说无论怎么转化都不可能有用更少的二的幂的个数来表示这个数,只能更多,也就是利用上…
题意:给定两个数字n,m,让你把数字 n 拆成一个长度为 m 的序列a1,a2,a3...am,并且∑2^ai = n,如果有多组,要求序列中最大的数最小,然后再相同就要求除了最大数字典序最大. 析:直接想可能不好想,可以考虑,如果把数字 n 拆成 2 的多次幂,可以用贪心来解决,然后如果长度已经超过了 m ,那么就是无解,否则就是有解,再考虑把这个序列变成 m 长度,因为要让最大的最小,所以,可以把最大的拆成两个,然后再看里面最大的是几个,如果序列当前长度加上序列中最大的数的数目,仍然不超过m…
思路: 先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成. 通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下一位那么就全部转换过去,如果不能就一个也不要转换,不然会导致字典序损失. 然后从最小的位开始转换,每次取出最小的位一个数,转换成下一位的两个,直到不能转换为止,这样就能保证字典序最大了,这个用优先队列维护下,可以直接求出来,直接for就可以了. 代码: #include<bits/stdc++.h>…
http://codeforces.com/problemset/problem/916/B 好尬啊... #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<map> using namespace std; #define fi first #define se second #define mp make_pair #define…
链接 大意: 求将n划分为k个2的幂的和, 且最大幂最小,字典序尽量大 比较简单的贪心练习题, 但放在div2的B题感觉偏难了..... 先只考虑最大幂最小, 首先注意到直接按n的二进制划分即可得到最小划分, 所以若k小于n二进制中1的个数的话显然不存在方案 否则若k足够大的话, 要使最高幂最小, 可以把最高幂可以分解成两个低次幂, 这样会使划分数增加1 基本思想就是用贪心从最坏状态调整到最优状态, 由于每次划分数加1, 一定可以达到k划分 但是这样划分完, 可以发现得到的划分字典序一定是最小的…
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把n分解成二进制的形式. n=2^a0+2^a1+...+2^a[q-1] 则固定就是长度为q的序列. 要想扩展为长为k的序列. 可以把2^x转化为2^(x-1)+2^(x-1)的形式. 这样序列的长度就+1了 它要求max{ai}最小 那么我们可以枚举ai的最大值是什么->i (递减着枚举) 然后比i大的ai都换成两个ai-1的形式. 然后看看序列的长度是否小于等于k; 如果小于k的话. 就把min{ai}分解成两个min{a…
题目大意 给一个数列,长度不超过 5000,每次可以将其中的一个数加 1 或者减 1,问,最少需要多少次操作,才能使得这个数列单调不降 数列中每个数为 -109-109 中的一个数 做法分析 先这样考虑:如果操作的次数最少,那么最终得到的不降的数列,必然是由原始数列中的数组成的,具体的证明可以使用反证法 知道了上面讲述的性质,这题就好搞了 先将原始数列(设为 A,共 n 个数)中所有的数去重并从小到达排序,保存在另一个数列中(设为 B,共 m 个数) 定义状态:f[i][j] 表示将原始数列中的…
题目传送门 /* 题意:刷墙,斜45度刷红色或蓝色,相交的成绿色,每次刷的是连续的一段,知道最终结果,问最少刷几次 模拟+思维:模拟能做,网上有更巧妙地做法,只要前一个不是一样的必然要刷一次,保证是最小的,脑洞大 */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; ; const int INF = 0x3f3f3…
https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则,假如u在v相邻前面,那么u和v可以交换位置,问你是队列最后一个人的时候你最前可以换到前面哪里 题解 因为相邻才能换,所以最后一个换到前面一定是一步一步向前走,所以不存在还要向后走的情况 设最后一个为u,假设前面有一个能和u换位置的集合,那么需要将这些点尽量往后移动去接u 假设前面有一个不能和u换位置的集合S,…
一起来学演化计算-SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 [1] https://blog.csdn.net/qq_36347331/article/details/96351162 [2] http://www.it1352.com/994287.html [3] https://www.egr.msu.edu/~kdeb…