Compare commits
No commits in common. "3f4d6cd144d12f357981f5c021041e08279f6cc1" and "34375a645783abebeb429b67b18ae11e0e913b87" have entirely different histories.
3f4d6cd144
...
34375a6457
|
@ -1,5 +1,2 @@
|
||||||
*.exe
|
*.exe
|
||||||
.vscode/*
|
.vscode/*
|
||||||
template/*
|
|
||||||
*.zip
|
|
||||||
*/datas/*
|
|
|
@ -1,5 +0,0 @@
|
||||||
1 4 3 2
|
|
||||||
1 4 5
|
|
||||||
8 2
|
|
||||||
3 5 2
|
|
||||||
4
|
|
|
@ -1,37 +0,0 @@
|
||||||
from cyaron import * # 引入CYaRon的库
|
|
||||||
|
|
||||||
T = 1000
|
|
||||||
n = 100
|
|
||||||
w = []
|
|
||||||
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
test_data = IO(file_prefix="./datas/t1_", data_id=i+1)
|
|
||||||
T = 10
|
|
||||||
n = randint(1, 10)
|
|
||||||
w = [randint(1, 4) for i in range(n)]
|
|
||||||
test_data.input_writeln(T)
|
|
||||||
test_data.input_writeln(n)
|
|
||||||
test_data.input_writeln(w)
|
|
||||||
test_data.output_gen("solution1.exe")
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
test_data = IO(file_prefix="./datas/t1_", data_id=i+11)
|
|
||||||
T = 30
|
|
||||||
n = randint(6, 10)
|
|
||||||
w = [randint(1, 10) for i in range(n)]
|
|
||||||
test_data.input_writeln(T)
|
|
||||||
test_data.input_writeln(n)
|
|
||||||
test_data.input_writeln(w)
|
|
||||||
test_data.output_gen("solution1.exe")
|
|
||||||
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
test_data = IO(file_prefix="./datas/t1_", data_id=i+21)
|
|
||||||
T = 50
|
|
||||||
n = randint(15, 35)
|
|
||||||
w = [randint(1, 4) for i in range(n)]
|
|
||||||
test_data.input_writeln(T)
|
|
||||||
test_data.input_writeln(n)
|
|
||||||
test_data.input_writeln(w)
|
|
||||||
test_data.output_gen("solution1.exe")
|
|
15
1/problem.md
15
1/problem.md
|
@ -1,15 +0,0 @@
|
||||||
## 问题描述
|
|
||||||
假设有一个能装入总体积为`T`的背包和`n`件体积分别为`w1,w2,…wn`的物品,能否从`n`件物品中挑选若干件恰好装背包,即使`w1+w2+…+wm=T`,要求找出所有满足上述条件的解。
|
|
||||||
例如:当`T=10`,各件物品的体积`{1,8,4,3,5,2}`时,可找到下列`4`组解:
|
|
||||||
- `(1,4,3,2)`
|
|
||||||
- `(1,4,5)`
|
|
||||||
- `(8,2)`
|
|
||||||
- `(3,5,2)`
|
|
||||||
|
|
||||||
## 实现提示
|
|
||||||
可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后,顺序选取物品装入背包,若已选取`i`件物品后未满,则继续选取第`i+1`件,若该件物品“太大”不能装入,则弃之,继续选取下一件,直至背包装满为。
|
|
||||||
|
|
||||||
如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入的物品“不合适”,应将它取出“弃之一”,继续再从“它之后”的物品中选取,如此重复,直到求得满足条件的解,或者无解。
|
|
||||||
|
|
||||||
由于回溯求解的规则是“后进先出”,自然要用到“栈”。
|
|
||||||
进一步考虑:如果每件物品都有体积和价值,背包又有大小限制,求解背包中存放物品总价值最大的问题解---最优解或近似最优解。
|
|
|
@ -1,48 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define MAX_N 100
|
|
||||||
|
|
||||||
int T;
|
|
||||||
int n;
|
|
||||||
int w[MAX_N];
|
|
||||||
int x[MAX_N];
|
|
||||||
int solution_count = 0;
|
|
||||||
|
|
||||||
// 暴力搜索,每个物品都有选和不选两种情况
|
|
||||||
void d(int t, int sum, int k) {
|
|
||||||
if (sum == T) {
|
|
||||||
solution_count++;
|
|
||||||
if (solution_count > 50)
|
|
||||||
return;
|
|
||||||
int *re = malloc(sizeof(int) * k);
|
|
||||||
int j = 0;
|
|
||||||
for (int i = 0; i < k; i++) {
|
|
||||||
if (x[i]) {
|
|
||||||
re[j++] = w[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < j; i++) {
|
|
||||||
printf("%d ", re[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
} else if (sum < T && k < n) {
|
|
||||||
x[k] = 1;
|
|
||||||
d(t + 1, sum + w[k], k + 1);
|
|
||||||
x[k] = 0;
|
|
||||||
d(t + 1, sum, k + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
// freopen("data.in", "r", stdin);
|
|
||||||
// freopen("data.out", "w", stdout);
|
|
||||||
scanf("%d", &T);
|
|
||||||
scanf("%d", &n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
scanf("%d", &w[i]);
|
|
||||||
}
|
|
||||||
d(0, 0, 0);
|
|
||||||
printf("%d", solution_count);
|
|
||||||
// printf("Total Solution Count: %d\n", solution_count);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
## 思路
|
|
||||||
一个能装入总体积为`T`的背包和`n`件体积分别为`w1,w2,…wn`的物品,能否从`n`件物品中挑选若干件恰好装背包,即使`w1+w2+…+wm=T`
|
|
||||||
|
|
||||||
相当于取一个向量 $n$ = $(x_1, x_2, ..., x_n)$,其中 $x_i \in \{0, 1\}$,使得 $\sum_{i=1}^n x_i w_i = T$,求所有满足条件的 $n$。
|
|
||||||
|
|
||||||
使用暴力 `dfs` 搜索,搜索每一件物品的选择情况,符合条件时输出。
|
|
||||||
|
|
||||||
总情况数为 $2^n$,时间复杂度为 $O(2^n)$。
|
|
||||||
|
|
||||||
## 代码及解释
|
|
|
@ -1,46 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define MAX_N 100
|
|
||||||
|
|
||||||
int T;
|
|
||||||
int n;
|
|
||||||
int w[MAX_N];
|
|
||||||
int x[MAX_N];
|
|
||||||
int solution_count = 0;
|
|
||||||
|
|
||||||
void dfs(int t, int sum, int k) {
|
|
||||||
if (sum == T) {
|
|
||||||
solution_count++;
|
|
||||||
int *re = malloc(sizeof(int) * k);
|
|
||||||
int j = 0;
|
|
||||||
for (int i = 0; i < k; i++) {
|
|
||||||
if (x[i]) {
|
|
||||||
re[j++] = w[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < j; i++) {
|
|
||||||
printf("%d ", re[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
} else if (sum < T && k < n) {
|
|
||||||
if (sum + w[k] <= T) {
|
|
||||||
x[k] = 1;
|
|
||||||
dfs(t + 1, sum + w[k], k + 1);
|
|
||||||
}
|
|
||||||
x[k] = 0;
|
|
||||||
dfs(t + 1, sum, k + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
freopen("data.in", "r", stdin);
|
|
||||||
freopen("data.out", "w", stdout);
|
|
||||||
scanf("%d", &T);
|
|
||||||
scanf("%d", &n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
scanf("%d", &w[i]);
|
|
||||||
}
|
|
||||||
dfs(0, 0, 0);
|
|
||||||
printf("Total Solution Count: %d\n", solution_count);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
## 思路
|
|
||||||
使用 `dfs`,搜索每一件物品的选择情况,符合条件时输出。
|
|
||||||
|
|
||||||
使用 `sum+w[k]<=T` 进行剪枝,提高运行速度
|
|
||||||
|
|
||||||
## 代码及解释
|
|
107
1/solution3.c
107
1/solution3.c
|
@ -1,107 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define MAX_N 100
|
|
||||||
|
|
||||||
int T;
|
|
||||||
int n;
|
|
||||||
int w[MAX_N];
|
|
||||||
int index_arr[MAX_N];
|
|
||||||
int solution_count = 0;
|
|
||||||
|
|
||||||
void printSubset(int *subset, int size) {
|
|
||||||
solution_count++;
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
printf("%d", subset[i]);
|
|
||||||
if (i != size - 1) {
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void findSubsets(int *arr, int n, int T, int *subset, int size, int index) {
|
|
||||||
if (T == 0) {
|
|
||||||
printSubset(subset, size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == n) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arr[index] > T) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
subset[size] = arr[index];
|
|
||||||
findSubsets(arr, n, T - arr[index], subset, size + 1, index + 1);
|
|
||||||
|
|
||||||
while (index < n - 1 && arr[index] == arr[index + 1]) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
findSubsets(arr, n, T, subset, size, index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void d(int *arr, int n, int T) {
|
|
||||||
int *subset = (int *)malloc(n * sizeof(int));
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
findSubsets(arr, n, T, subset, size, 0);
|
|
||||||
|
|
||||||
free(subset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(int *arr, int i, int j) {
|
|
||||||
int tmp = arr[i];
|
|
||||||
arr[i] = arr[j];
|
|
||||||
arr[j] = tmp;
|
|
||||||
|
|
||||||
tmp = index_arr[i];
|
|
||||||
index_arr[i] = index_arr[j];
|
|
||||||
index_arr[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort(int *arr, int n) {
|
|
||||||
int i = 0, j = n - 1;
|
|
||||||
int pivot = arr[0];
|
|
||||||
int pivot_index = 0;
|
|
||||||
while (i < j) {
|
|
||||||
while (i < j && arr[j] >= pivot) {
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
if (i < j) {
|
|
||||||
swap(arr, i, j);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (i < j && arr[i] <= pivot) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (i < j) {
|
|
||||||
swap(arr, i, j);
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
freopen("data.in", "r", stdin);
|
|
||||||
// freopen("data.out", "w", stdout);
|
|
||||||
scanf("%d", &T);
|
|
||||||
scanf("%d", &n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
scanf("%d", &w[i]);
|
|
||||||
index_arr[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
sort(w, n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
printf("%d ", w[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
|
|
||||||
d(w, n, T);
|
|
||||||
// printf("Total Solution Count: %d\n", solution_count);
|
|
||||||
printf("%d", solution_count);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue