首页 > 代码库 > codechef 2014/12
codechef 2014/12
总是只能做4、5题,要加油啊!
1. XORSUB
You are given an array A of N integers and an integer K. Your task is to return the maximum possible value of F(P) xor K, where P is a subset of A and F(P) is defined as a xor of all values in P. If P is empty, then F(P) = 0.
题目刚出的时候没说A中的元素是<=1000的,于是就不会做了。后来这个条件出来了,就很自然能想到dp了。
在论坛看到一种高斯消元的解法(用异或来消,使得最高位成上三角),想想挺有道理的,因为得到的还是等价表示,消去前的XOR集合能用消去后的表示。消去后从大到小处理,显然后面小的数不会影响到目前已有结果,贪心即可。而且这个方法不受A[i]<=1000的限制。
补个链接 http://math.stackexchange.com/questions/48682/maximization-with-xor-operator
2. 把N个数分到K个集合,能否使得每个集合的元素和相等。N<=21, K<=8.
我是直接用搜索做的,先把元素从大到小排序,搜索时规定对于集合间按最大元素从大到小搜,集合内也按从大到小的顺序。题解是用dp做的,这个真没想到,需要注意吸收。
另每个集合的和为x, dp[k][bitmask] = 1表示能用bitmask(位压缩)表示的元素集合刚好分配到k个集合中,使得每个集合的和为x,或者分配后还剩下的元素和小于x。
for k = 0 to K - 1: for bitmask = 0 to 2^n - 1: if not dp[k][bitmask]: continue sum = 0 for i = 0 to n - 1: if (bitmask & (1LL << i)): sum += a[i] sum -= k * x for i = 0 to n - 1: if (bitmask & (1LL << i)): continue //there is nothing to extend new_mask = bitmask | (1LL << i) //bitmask denoting a set with i-th element added if sum + a[i] == x: //we can fill the k+1 th subset with elements of sum X using a set of elements denoted by new_mask dp[k + 1][new_mask] = 1 else if sum + a[i] < x: //we can fill k subsets with elements of sum X and one subsets with sum < X using a set of elements denoted by new_mask dp[k][new_mask] = 1if dp[K][2^n - 1] == 1: print "yes"else: print "no"
复杂度O(K * 2^N * N)
3. N个范围为1~M的整数,求最大公约数在L~R之间的方式之和。M,N<=10^7
这题看了题解之后才发现应该做出来的。。。
另f(m)为1~m的n个数最大公约数d为1的方法数,则需排除d>1的情况,即f(m)=m^n-f(m/2)-f(m/3)-...-f(m/m)
到了这里原来就没继续下去了,因为觉得复杂度太高。。看了题解才发现其实不然。在算出了f(m/2)等项后,算f(m)要m次。那么求出所有项需要m+m/2+m/3+...+m/m=m*(1+1/2+1/3+...+1/m),结果是m*ln(m),按题目的时限,并不高。
结果是f(M/L)+...+f(M/R)
codechef 2014/12