这个问题可以等价为:枚举从N个整数中选择K个数,这K个数满足一定的条件。
给定N个整数(可能有负数),从中选取K个数,,使得这K个数之和恰好为X,如果有多种方案,选择他们中元素平方和最大的一组。(数据保证有唯一性),例如从4个整数中{2,3,3,4}中选择2个数,使他们的和为6,显然有两种方案,{2,4},{3,3},其中平方和最大的是{2,4};
函数声明:void DFS(int index, int sum_k, int sum,int sum_squ ) ;
index:记录当前处理整数的编号 sum_k是选择的K个数,sum是已选数的和;sum_squ是已选数的平方和
void DFS(int index, int sum_k, int sum,int sum_squ ) {
if (sum_k == k&&sum == x) {
if (sum_squ > maxsumsqu) {
maxsumsqu = sum_squ;
ans = temp;
}
return;
}
if (index == n || sum_k > k || sum > x) {
return;
}
temp.push_back(A[index]);
//选
DFS(index + 1, sum_k + 1, sum + A[index], sum_squ + A[index] * A[index]);
temp.pop_back();
//不选
DFS(index + 1, sum_k , sum, sum_squ);
}
全部函数:
#include "stdafx.h"
#include<vector>#include<iostream>
#include<stdio.h>
using namespace std;
//变量声明
const int maxn = 100000;
int n, k, x;
vector<int> temp, ans;
int maxsumsqu = -1;
int A[maxn];
void DFS(int index, int sum_k, int sum,int sum_squ ) {
if (sum_k == k&&sum == x) {
if (sum_squ > maxsumsqu) {
maxsumsqu = sum_squ;
ans = temp;
}
return;
}
if (index == n || sum_k > k || sum > x) {
return;
}
temp.push_back(A[index]);
//选
DFS(index + 1, sum_k + 1, sum + A[index], sum_squ + A[index] * A[index]);
temp.pop_back();
//不选
DFS(index + 1, sum_k , sum, sum_squ);
}
int main() {
cin >> n >> k >> x ;
for (int i = 0;i < n;i++) {
scanf_s("%d", &A[i]);
}
DFS(0,0, 0,0);
vector <int> ::iterator it;
it = ans.begin();
printf("%d\n", maxsumsqu);
printf("%d %d\n", *it ,*(it+1));
return 0;
}
上面针对的问题是每个数只可选一次,稍微修改为:假如N个整数中的每一个都可以被选择多次,那么选择K个数,使得K个数之和恰好为X。
假如有3个整数{1,4,7},选5个数,使得5个数之和为17,显然,只需要选择3个1,和2个7,程序修改为:
#include "stdafx.h"
#include<vector>
#include<iostream>
#include<stdio.h>
using namespace std;
//变量声明
const int maxn = 100000;
int n, k, x;
vector<int> temp, ans;
int maxsumsqu = -1;
int A[maxn];
void DFS(int index, int sum_k, int sum, int sum_squ) {
if (sum_k == k&&sum == x) {
if (sum_squ > maxsumsqu) {
maxsumsqu = sum_squ;
ans = temp;
}
return;
}
if (index == n || sum_k > k || sum > x) {
return;
}
temp.push_back(A[index]);
//选
if (sum_k == k) {
DFS(index + 1, sum_k + 1, sum + A[index], sum_squ + A[index] * A[index]);
}
else {
DFS(index , sum_k + 1, sum + A[index], sum_squ + A[index] * A[index]);
}
//DFS(index + 1, sum_k + 1, sum + A[index], sum_squ + A[index] * A[index]);
temp.pop_back();
//不选
DFS(index + 1, sum_k, sum, sum_squ);
}
int main() {
cin >> n >> k >> x;
for (int i = 0;i < n;i++) {
scanf_s("%d", &A[i]);
}
DFS(0, 0, 0, 0);
vector <int> ::iterator it;
it = ans.begin();
printf("%d\n", maxsumsqu);
for (int i = 0;i < 5;i++) {
printf("%d \n", *(it++));
}
return 0;
}