从给定的N个正数中选取若干个数之和最接近M

时间:2021-08-12 17:43:33

http://www.ahathinking.com/archives/110.html

这道题跟捞鱼问题一样,都是刚进实验室新生培训那会儿做过的题目,不过这个是一师姐当时找工作的面试题。

如题,并输出该子序列

测试用例:2,9,5,7,4,11,10

分别输出最接近33、40、47、60的子序列

分析:N个数之和接近M,将M看做一个容量的背包,这个题目就变成了典型的01背包,M容量下求最优解并输出最优方案,这在01背包中都整理过,上代码:


#include <iostream>
using namespace std;

char state[11][101]; /* 设 N <= 10 M <= 100 记录路径 */
int dp[101]; /* 使用一维数组01背包 */
int value[11]; /* 本题可将费用与价值看做同一值 */
int i, j;

void main()
{
int N, M;
scanf("%d", &N);
for(i = 0; i < N; ++i)
{
scanf("%d",&value[i]);
}

while(scanf("%d", &M) != EOF)
{
memset(dp,0,sizeof(dp));

/* 01背包 */
for(i = 0; i < N; ++i)
{
for(j = M; j >= value[i]; --j)
{
int tmp = dp[j-value[i]] + value[i];
if(tmp > dp[j])
{
dp[j] = tmp;
state[i][j] = 1;
}
}
}
printf("最接近值:%d\n",dp[M]);

/* 输出方案 */
i = N;
j = M;
while(i-- >= 0)
{
if(state[i][j] == 1)
{
printf("%d ",value[i]);
j -= value[i];
}
}
printf("\n");
}
}
输出结果如下图