• [codility]Min-abs-sum


    https://codility.com/demo/take-sample-test/delta2011/

    0-1背包问题的应用。我自己一开始没想出来。“首先对数组做处理,负数转换成对应正数,零去掉,计数排序统计有多少个不同元素及其对应个数,并累加所有数的和sum,不妨记b=sum/2,不同元素个数为m,则目标转换为在m个不同元素中挑出若干个元素(每个元素可以重复多次,但少于它们的出现次数),使得它们的和不大于b并尽量接近。到了这里,应该有点熟悉的感觉了吧。对了,其实这就是0-1背包问题!” 参考http://phiphy618.blogspot.jp/2013/05/codility-delta-2011-minabssum.html

    第一次的代码并未完全通过,75分,大数据全挂。原因是这里一个元素可以出现多次,是多重背包问题。

    // you can also use imports, for example:
    // import java.math.*;
    class Solution {
        public int solution(int[] A) {
            // write your code here...
        	if (A.length == 0) return 0;
        	
        	int sum = 0;
        	int max = 0;
        	for (int i = 0; i < A.length; i++) {
        		if (A[i] < 0) A[i] = -A[i];
        		sum += A[i];
        	}
        	int target = sum / 2;
        	int dp[][] = new int[A.length][target];
        	for (int i = 0; i < A.length; i++) {
        		for (int j = 0; j < target; j++) {
        			// j+1 is the weight limit
        			if (i == 0)
        			{
        				if (A[i] <= (j+1)) {
        					dp[i][j] = A[i];
        				}
        				else
        				{
        					dp[i][j] = 0;
        				}
        			}
        			else // i != 0
        			{
        				int w1 = dp[i-1][j];
        				int w2 = 0;
        				if (j-A[i] >=0 ) {
        					w2 = dp[i][j-A[i]] + A[i];
        				}
        				dp[i][j] = w1 > w2 ? w1 : w2;
        			}
        		}
        	}
        	max = dp[A.length - 1][target - 1];
        	return (sum - max * 2);
        }
    }
    

    第二次参考了cp博士的文章,处理了多重背包的优化,并用了滚动数组:http://blog.csdn.net/caopengcs/article/details/10028269

    // you can also use includes, for example:
    // #include <algorithm>
    int solution(const vector<int> &A) {
        // write your code in C++98
        int len = A.size();
        int sum = 0;
        int M = 0;
        for (int i = 0; i < len; i++) {
            int x = 0;
            x = A[i] > 0 ? A[i] : -A[i];
            sum += x;
            if (x > M)
                M = x;
        }
        vector<int> count;
        count.resize(M+1);
        for (int i = 0; i < len; i++) {
            int x = 0;
            x = A[i] > 0 ? A[i] : - A[i];
            count[x]++;
        }
        int target = sum / 2;
        int largest = 0;
        vector<int> dp(target+1, -1);
        for (int i = 0; i <= M; i++) {
            if (count[i] > 0) {
                for (int j = 0; j <= target; j++) {
                    if (j == 0) dp[j] = count[i];
                    if (dp[j] >= 0) {
                        dp[j] = count[i];
                        if (j > largest)
                            largest = j;
                    }
                    else if (j - i >= 0 && dp[j - i] > 0) {
                        dp[j] = dp[j - i] - 1;
                        if (j > largest)
                            largest = j;
                    }
                    else {
                        dp[j] = -1;
                    }
                }
            }
        }
        return abs(sum - 2 * largest);
    }
    

      

      

  • 相关阅读:
    js中url跳转问题
    代码走查整理总结
    关于前后端分离跨域请求问题
    mysql大小写敏感问题
    初识react
    mysql测试
    关于使用Ajax请求json数据,@RequestMapping返回中文乱码的几种解决办法
    ssm实现分页查询
    js表单验证处理和childNodes 和children 的区别
    javaScript数组操作整理
  • 原文地址:https://www.cnblogs.com/lautsie/p/3228644.html
Copyright © 2020-2023  润新知