为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1482
小明用计算机随机生成了 N N N个正整数,他希望从这 N N N个数中选取若干个数,使得它们的和等于 M M M。这些随机生或的数字可能会相同,但是每个数字最多只允许使用一次。
当然这样的选取方案可能不存在,也可能有多个。
现在希望你编写一个程序,能够找出数字个数最少的选取方案,输出对应的最少数字的个数。如果无解输出" N o No No s o l u t i o n solution solution"
单单组输入,每组输入 2 2 2行。
第 1 1 1行包含两个正整数 N N N和 M M M,分别表示初始输入的正整数个数和目标数字和( N ≤ 1 e 3 , m ≤ 1 e 5 N \leq 1e3,m \leq 1e5 N≤1e3,m≤1e5)
第 2 2 2行为 N N N个正整数,两两之间用空格隔开(每一个正整数均小于等于 l e 5 le5 le5)。
输出数字个数最少的选取方案中所有包含的最少数字个数,如果无解输出" N o No No $solution $"
输入
5 5
1 3 2 1 1
输出
2
小明用计算机随机生成了 N N N个正整数,他希望从这 N N N个数中选取若干个数,使得它们的和等于 M M M。这些随机生或的数字可能会相同,但是每个数字最多只允许使用一次。
当然这样的选取方案可能不存在,也可能有多个。
现在希望你编写一个程序,能够找出数字个数最少的选取方案,输出对应的最少数字的个数。如果无解输出" N o s o l u t i o n No solution Nosolution"
单单组输入,每组输入 2 2 2行。
第 1 1 1行包含两个正整数 N N N和 M M M,分别表示初始输入的正整数个数和目标数字和( N ≤ 1 e 3 , m ≤ 1 e 5 N \leq 1e3,m \leq 1e5 N≤1e3,m≤1e5)
第 2 2 2行为 N N N个正整数,两两之间用空格隔开(每一个正整数均小于等于 l e 5 le5 le5)。
输出数字个数最少的选取方案中所有包含的最少数字个数,如果无解输出" N o s o l u t i o n No solution Nosolution "
输入
5 5
1 3 2 1 1
输出
2
这里考虑通过n
个数字来拼凑出一个m
,那么显然是一个01背包
。
关于01背包的问题,这里不做过多的赘述,可以参考这里或者这里.
Cpp代码
#include
using namespace std;
const int maxn = 1e5 + 10;
int a[1010];
int f[maxn];
int main()
{
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
memset(f, 0x3f, sizeof(f));
const int st = f[0];
f[0] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= a[i]; j--)
{
f[j] = min(f[j], f[j - a[i]] + 1);
}
}
if (f[m] == st)
{
cout << "No solution" << endl;
}
else
cout << f[m] << endl;
}
java代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int N = 1<<30;
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[] nums = new int[n + 1];
for (int i = 1; i <= n; i++) {
nums[i] = scanner.nextInt();
}
int[] f = new int[m + 1];
Arrays.fill(f, N);
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = m; j >= nums[i]; j--) {
f[j] = Math.min(f[j], f[j - nums[i]] + 1);
}
for (int k : f)
System.out.print(k + " ");
System.out.println();
}
if (f[m] == N) {
System.out.println("No solution");
} else {
System.out.println(f[m]);
}
}
}
python代码
if __name__ == "__main__":
n, m = map(int, input().split())
a = list(map(int, input().split()))
f = [1e9 for i in range(0, m + 1)]
f[0] = 0
for i in range(0, n):
for j in range(m , a[i] - 1, -1):
f[j] = min(f[j], f[j - a[i]] + 1)
if(f[m] == 1e9):
print("No solution")
else:
print(f[m])