[1, N] 范围内不具有任何子集总和为 K 的不同整数的计数
给定两个正整数N和K ,使得K≤N,任务是找到范围[1, N]中不存在总和等于K的子集的不同整数的最大数量。如果有多个解决方案,请打印任何一个。
例子:
Input: N = 5, K = 3
Output: 1 4 5
Explanation: There are two sets of distinct numbers of size 3 which don’t have any subset sum of 3.
These are {1, 4, 5} and {2, 4, 5}. So, print any of them in any order.
Input: N = 1, K =1
Output: 0
方法:这个想法基于以下观察:
- 可以选择任何大于K的数字,因为它们永远不会对总和为K的子集做出贡献。
- 无法选择K。
- 对于小于K的数字,最多可以选择K/2 个数字。例如:
- 如果K =5、1+4=5、2+3=5,那么可以选择1或者4,同样可以选择2或者3。因此,最多可以选择 (5/2=2) 个数字。
- 如果K =6, 1+5=6, 2+4=6 和 3+3=6。同样,可以选择 3 个数字,使得没有子集和等于 6。始终可以选择 3,因为只选择不同的数字,并且可以选择 1 或 5,类似地可以选择 2 或 4。因此,最多可以选择(6/3=3)个数字。
- 因此,可以选择的不同数字的最大数量是(NK)+(K/2) 。
请按照以下步骤解决问题:
- 可以选择的不同数字的最大数量是(NK)+(K/2) 。
- 需要选择所有大于K的数字,即从末尾开始的NK 个数字。还需要选择小于K的K/2 个元素。
- 因此,一种可能的解决方案是从N开始选择(NK)+(K/2)个连续数字,不包括K 。
- 最简单的方法是创建一个数组,存储从1到N的所有值,除了K ,反转数组,并从头开始打印(NK)+(K/2) 个元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find maximum number of distinct integers
// in [1, N] having no subset with sum equal to K
void findSet(int N, int K)
{
// Declare a vector to store
// the required numbers
vector a;
// Store all the numbers in [1, N] except K
for (int i = 1; i <= N; i++) {
if (i != K)
a.push_back(i);
}
// Store the maximum number
// of distinct numbers
int MaxDistinct = (N - K) + (K / 2);
// Reverse the array
reverse(a.begin(), a.end());
// Print the required numbers
for (int i = 0; i < MaxDistinct; i++)
cout << a[i] << " ";
}
// Driver Code
int main()
{
// Given Input
int N = 5, K = 3;
// Function Call
findSet(N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find maximum number of distinct
// integers in [1, N] having no subset with
// sum equal to K
static void findSet(int N, int K)
{
// Declare a vector to store
// the required numbers
ArrayList a = new ArrayList();
// Store all the numbers in [1, N] except K
for(int i = 1; i <= N; i++)
{
if (i != K)
a.add(i);
}
// Store the maximum number
// of distinct numbers
int MaxDistinct = (N - K) + (K / 2);
// Reverse the array
Collections.reverse(a);
// Print the required numbers
for(int i = 0; i < MaxDistinct; i++)
System.out.print(a.get(i) + " ");
}
// Driver Code
public static void main(String[] args)
{
// Given Input
int N = 5, K = 3;
// Function Call
findSet(N, K);
}
}
// This code is contributed by sanjoy_62
Python3
# Python3 program for the above approach
# Function to find maximum number of distinct
# integers in [1, N] having no subset with
# sum equal to K
def findSet(N, K):
# Declare a vector to store
# the required numbers
a = []
# Store all the numbers in [1, N] except K
for i in range(1, N + 1):
if (i != K):
a.append(i)
# Store the maximum number
# of distinct numbers
MaxDistinct = (N - K) + (K // 2)
# Reverse the array
a = a[::-1]
# Print the required numbers
for i in range(MaxDistinct):
print(a[i], end = " ")
# Driver Code
if __name__ == '__main__':
# Given Input
N = 5
K = 3
# Function Call
findSet(N, K)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find maximum number of distinct
// integers in [1, N] having no subset with
// sum equal to K
static void findSet(int N, int K)
{
// Declare a vector to store
// the required numbers
List a = new List();
// Store all the numbers in [1, N] except K
for(int i = 1; i <= N; i++)
{
if (i != K)
a.Add(i);
}
// Store the maximum number
// of distinct numbers
int MaxDistinct = (N - K) + (K / 2);
// Reverse the array
a.Reverse();
// Print the required numbers
for(int i = 0; i < MaxDistinct; i++)
Console.Write(a[i] + " ");
}
// Driver Code
public static void Main()
{
// Given Input
int N = 5, K = 3;
// Function Call
findSet(N, K);
}
}
// This code is contributed by avijitmondal1998.
Javascript
输出
5 4 2
时间复杂度: O(N)
辅助空间: O(N)