zoukankan      html  css  js  c++  java
  • 1755. Closest Subsequence Sum

    题目

    题意:从一个数组找出一个子集,使得子集的和给定的目标最相近。

    题解:数组的长度为40,找出全部子集一共有240种可能性,如果把一个数组平均分成两部分,分别算出两部分的所有子集和,每部分有220种可能,
    然后再二分查找答案。

    遇到这种在数组里找所有子集和,

    class Solution {
    public:
       map<int, int> m;
    int sum[1000005];
    int sum2[1000005];
    int p;
    void fun(int n, int i, int s,vector<int>& nums, int* sum)
    {
    	if (m[s] == 0)
    	{
    		m[s] = 1;
    		sum[p++] = s;
    	}
    	
    	for (int j = i + 1; j < n; j++)
    	{
    		fun(n, j, s+nums[j], nums, sum);
    	}
    }
        
        int minAbsDifference(vector<int>& nums, int goal)
    {
    	int ans = INT_MAX;
    	int n = nums.size()/2;
    	p = 0;
    	for (int i = 0; i < n; i++)
    	{
    		fun(n, i, nums[i], nums, sum);
    	}
    	int p1 = p;
    	m.clear();
    	for (int i = 0; i < p1; i++)
    	{
    		ans = min(ans, abs(sum[i] - goal));
    	}
    	p = 0;
    	for (int i = n; i < nums.size(); i++)
    	{
    		fun(nums.size(), i, nums[i],nums, sum2);
    	}
    	for (int i = 0; i < p; i++)
    	{
    		ans = min(ans, abs(sum2[i] - goal));
    	}
    
    	sort(sum, sum + p1);
    	
    	// 1 2 5 6
    	for (int i = 0; i < p; i++)
    	{
    		int x = sum2[i];
    
    		int l = 0;
    		int r = p1;
    
    		while (l <= r)
    		{
    			int mid = (l + r) / 2;
    			ans = min(ans, abs(sum[mid] + x - goal));
    			if (sum[mid] + x > goal)
    			{
    				r = mid - 1;
    			}
    			else if (sum[mid] + x < goal)
    			{
    				l = mid + 1;
    			}
    			else
    			{
    				return 0;
    			}
    		}
    	}
    	return ans;
    }
    
    
    };
    
  • 相关阅读:
    双边沿采样
    `ifdef、`else、`endif 用法
    交通信号灯
    异步复位同步释放
    用Verilog来实现d触发器2分频的Verilog hdl程序
    谈谈Mux与门电路的相互替换(包含实例分析)
    数字电路笔试题
    仰视奶牛
    单调栈
    div2 620 C
  • 原文地址:https://www.cnblogs.com/dacc123/p/14400440.html
Copyright © 2011-2022 走看看