小易的幸运数字是7,现有一个整数数组 nums,请你找出并返回能被七整除的子集合的最大和,如果找不到则返回-1。
一个正整数数组列表nums,用空格区分,1<=length(nums)<=100000,sum(nums) <= 1000000000
一个整数,最大和
7 3 1 4
14
7+3+4
6 5
-1
找不到 一个子数组,和能被7整除
10 20 2 29
49
20+29
这道题很难, 一开始会想到遍历得到所有的子集合的和, 但是却不知道如何遍历得到。因为这里的子集合长度可以为1 ~ nums.length,一般的遍历无法满足!
举例: 1 2 3 4
一般的遍历是 1, 1 2, 1 2 3, 1 2 3 4, 2, 2 3, 2 3 4, 3,3 4,4实现这个遍历已经是O(n^2)的复杂度了! 可是这还没结束, 还需要 1 3, 1 3 4, 1 4, 2 4, 这种循环遍历极其难写出来!!
🌟那我们这里想到了一个巧妙地方法, 逆向思维, 由于全部的数之和sum肯定是由所有的数组成, 那我们可以试着慢慢地扒元素下来直到把所有元素扒完,
const readline=require('readline');
const rl=readline.createInterface({
input:process.stdin,
output:process.stdout
});
/*
小易的幸运数字是7,现有一个整数数组 nums,
请你找出并返回能被七整除的子集合的最大和,如果找不到则返回-1
输入:
一个正整数数组列表nums,用空格区分,1<=length(nums)<=100000,sum(nums) <= 1000000000
*/
rl.on('line',function (line) {
/*1.处理数据*/
let arr=line.trim().split(' ').map(Number);
/*2.dp*/
//由于是全是正整数,所以 sum >= arr.length
let sum=arr.reduce((a,b)=>a+b);
//dp[i]记录i是否能够得到 1为可得到,0则相反
let dp=new Array(sum+1).fill(0);
dp[0]=1; dp[sum]=1;
/*这个方法很巧妙, 最初是a+b+c+d,每次从所有的满足条件的子集合减去一个数
* 这样就很方便的得到了所有的排列*/
for (let i=0;i<arr.length;i++){
for (let j=0;j<=sum;j++){
if (dp[j]===1&&j>=arr[i]){
dp[j-arr[i]]=1;
}
}
}
let maxSum=-1;
for (let i=dp.length-1;i>=7;i--){
if (dp[i]===1&& i%7===0){
maxSum=i;
break;
}
}
console.log(maxSum);
}) lyst = list(map(int, input().split())) # 数组所有数字之和 total = 0 for i in lyst: total += i # 数组排序 lyst.sort() res = [total] flag = False for i in lyst: # 注意此处不能直接用res循环,否则后面append之后res长度增加还会继续循环内层 res_set = set(res) for j in res_set: temp = j - i if temp % 7 == 0: flag = True print(temp) break else: res.append(temp) if flag: break if not flag: print(-1)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strArr = br.readLine().split(" ");
int[] arr = new int[strArr.length];
int sum = 0;
for(int i = 0; i < strArr.length; i++) {
arr[i] = Integer.parseInt(strArr[i]);
sum += arr[i];
}
// 求解背包问题
int[] dp = new int[sum + 1]; // dp[i]用来记录i是否能得到
dp[0] = 1;
dp[sum] = 1;
for(int i = 0; i < arr.length; i++){
dp[i] = 1;
for(int j = 0; j <= sum; j++)
if(dp[j] == 1 && j >= arr[i]) dp[j - arr[i]] = 1;
}
// 降序遍历能取到的总和,输出最大的
for(int lucky = sum; lucky >= 0; lucky--){
if(dp[lucky] == 1 && lucky % 7 == 0){
System.out.println(lucky);
break;
}
}
}
} import sys from math import inf l = [int(s) for s in input().split()] l.sort() n = len(l) prev = [0] * 7 prev[l[0] % 7] = l[0] for i in range(1, n): dp = prev.copy() cur = l[i] % 7 dp[cur] = max(prev[cur], l[i]) for j in range(7): if prev[j] != 0: idx = (j + l[i]) % 7 dp[idx] = max(prev[idx], prev[j] + l[i]) prev = dp print(prev[0])
#include<iostream>
#include<vector>
using namespace::std;
int main()
{
vector<int> nums;
int x;
long sum;
do{
cin>>x;
nums.push_back(x);
sum+=x;
}while(cin.get()!='\n');
vector<vector<int>> dp(nums.size()+1,vector<int>(7,sum));
dp[0][sum%7]=0;
for(int i=1;i<nums.size()+1;i++)
{
int x=nums[i-1];
for(int j=0;j<7;j++)
{
dp[i][j]=min(dp[i-1][j],dp[i-1][(x%7+j)%7]+x);
}
}
cout<<sum-dp.back()[0]<<endl;
} //暴力搜索
#include <bits/stdc++.h>
using namespace std;
int ret = 0;
void backTracking(const vector<int>& nums,int sum, int index)
{
if(index >= nums.size())
{
if(sum % 7 == 0)
ret = max(ret, sum);
return;
}
for(int i = index;i < nums.size();i++)
{
sum += nums[i];
backTracking(nums, sum, i+1);
sum -= nums[i];
}
}
int main()
{
vector<int> nums;
int num;
while(cin >> num)
nums.push_back(num);
backTracking(nums, 0, 0);
cout << ret << endl;
return 0;
} #include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
vector<int> nums;
int max_sum = -1;
int sum = 0;
while(scanf("%d", &n) != EOF)
{
sum += n;
int rest = n % 7;
// 加入所有7的整数倍
if(rest != 0)
{
nums.push_back(n);
}
}
int rest = sum % 7;
// 刚好是7的倍数
if(rest == 0)
{
cout << sum << endl;
return 0;
}
//每组都排序
sort(nums.begin(), nums.end());
int tmp_sum = 0;
function <void(int)> dfs =
[&](int deps)
{
if(deps == -1)
{
return ;
}
// 不加入直接判断
if(tmp_sum % 7 == rest && tmp_sum != sum)
{
max_sum = sum - tmp_sum;
return ;
}
dfs(deps - 1);
// 加入
tmp_sum += nums[deps];
if(tmp_sum % 7 == rest && tmp_sum != sum)
{
max_sum = sum - tmp_sum;
return ;
}
dfs(deps - 1);
//还原
tmp_sum -= nums[deps];
return ;
};
for(int i = 0; i < nums.size(); i++)
{
tmp_sum = 0;
dfs(i);
if(max_sum != -1)
{
break;
}
}
cout << max_sum << endl;
return 0;
} import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] ss = reader.readLine().split(" ");
Set<Integer> set=new HashSet();
set.add(0);
Integer ans=Integer.MIN_VALUE;
for(String s:ss ){
Iterator<Integer> it=set.iterator();
Set<Integer> set2=new HashSet();
while(it.hasNext()){
Integer t=it.next();
Integer v=Integer.parseInt(s)+t;
set2.add(t);
set2.add(v);
if(v%7==0 && v>ans){
ans=v;
}
}
set=set2;
}
if(ans==Integer.MIN_VALUE){
System.out.println(-1);
}
else{
System.out.println(ans);
}
}
} import java.io.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] s = reader.readLine().split(" ");
int sum = 0;
int[] arr = new int[s.length];
for(int i = 0 ; i < s.length ;i++){
arr[i] = Integer.parseInt(s[i]);
sum += arr[i];
}
int[] dp = new int[sum+1];
dp[sum] = 1; dp[0] = 1;
for(int i = 0 ; i < arr.length;i++){
for(int j = 0; j <= sum;j++)
if(dp[j] == 1 && j >= arr[i]) dp[j - arr[i]] = 1;
}
for(int lucky = sum; lucky >= 0; lucky--){
if(dp[lucky] == 1 && lucky % 7 == 0){
System.out.println(lucky);
break;
}
}
}
}