diff --git a/1/data.in b/1/data.in index 0ffe6ae..9742b21 100644 --- a/1/data.in +++ b/1/data.in @@ -1,3 +1,3 @@ -30 -9 -10 10 8 6 6 5 10 8 4 +10 +6 +1 8 4 3 5 2 \ No newline at end of file diff --git a/1/data.out b/1/data.out deleted file mode 100644 index 85a7dc9..0000000 --- a/1/data.out +++ /dev/null @@ -1,12 +0,0 @@ -4 10 6 10 -4 10 6 10 -4 8 10 8 -4 8 8 10 -4 6 10 10 -10 8 6 6 -10 10 10 -8 6 6 10 -8 6 6 10 -6 6 10 8 -6 6 8 10 -11 \ No newline at end of file diff --git a/1/dp.c b/1/dp.c new file mode 100644 index 0000000..9d3e537 --- /dev/null +++ b/1/dp.c @@ -0,0 +1,33 @@ +#include +#include + +int T, M, t[105], w[105]; +int dp[1005][1005]; + +int max(int a, int b) { return a > b ? a : b; } + +int main() { + freopen("dp.in", "r", stdin); + scanf("%d%d", &T, &M); + for (int i = 1; i <= M; i++) { + scanf("%d%d", &t[i], &w[i]); + } + dp[0][0] = 0; + for (int i = 1; i <= M; i++) { + for (int j = 1; j <= T; j++) { + if (j < t[i]) + dp[i][j] = dp[i - 1][j]; + else + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - t[i]] + w[i]); + } + } + printf("%d\n", dp[M][T]); + // for(int i=1;i<=M;i++){ + // for(int j=1;j<=T;j++){ + // printf("%d ",dp[i][j]); + // } + // printf("\n"); + // } + + return 0; +} \ No newline at end of file diff --git a/1/dp.in b/1/dp.in new file mode 100644 index 0000000..0b82d78 --- /dev/null +++ b/1/dp.in @@ -0,0 +1,4 @@ +70 3 +71 100 +69 1 +1 2 \ No newline at end of file diff --git a/1/dp.md b/1/dp.md new file mode 100644 index 0000000..b15c446 --- /dev/null +++ b/1/dp.md @@ -0,0 +1,47 @@ +# 参考洛谷 +# P1048 [NOIP2005 普及组] 采药 + +## 题目描述 + +辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” + + +如果你是辰辰,你能完成这个任务吗? + +## 输入格式 + +第一行有 $2$ 个整数 $T$($1 \le T \le 1000$)和 $M$($1 \le M \le 100$),用一个空格隔开,$T$ 代表总共能够用来采药的时间,$M$ 代表山洞里的草药的数目。 + +接下来的 $M$ 行每行包括两个在 $1$ 到 $100$ 之间(包括 $1$ 和 $100$)的整数,分别表示采摘某株草药的时间和这株草药的价值。 + +## 输出格式 + +输出在规定的时间内可以采到的草药的最大总价值。 + +## 样例 #1 + +### 样例输入 #1 + +``` +70 3 +71 100 +69 1 +1 2 +``` + +### 样例输出 #1 + +``` +3 +``` + +## 提示 + +**【数据范围】** + +- 对于 $30\%$ 的数据,$M \le 10$; +- 对于全部的数据,$M \le 100$。 + +**【题目来源】** + +NOIP 2005 普及组第三题 \ No newline at end of file diff --git a/1/solution2.c b/1/main.c similarity index 94% rename from 1/solution2.c rename to 1/main.c index c2e2676..2ba1e27 100644 --- a/1/solution2.c +++ b/1/main.c @@ -25,6 +25,7 @@ void dfs(int t, int sum, int k) { } printf("\n"); } else if (sum < T && k < n) { + // 剪枝 if (sum + w[k] <= T) { x[k] = 1; dfs(t + 1, sum + w[k], k + 1); @@ -36,7 +37,7 @@ void dfs(int t, int sum, int k) { int main() { freopen("data.in", "r", stdin); - freopen("data.out", "w", stdout); + // freopen("data.out", "w", stdout); scanf("%d", &T); scanf("%d", &n); for (int i = 0; i < n; i++) { diff --git a/1/solution1.c b/1/solution1.c deleted file mode 100644 index bf15a65..0000000 --- a/1/solution1.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#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; -} diff --git a/1/solution1.md b/1/solution1.md index b8e68d3..0ef7331 100644 --- a/1/solution1.md +++ b/1/solution1.md @@ -5,6 +5,8 @@ 使用暴力 `dfs` 搜索,搜索每一件物品的选择情况,符合条件时输出。 +使用 `sum+w[k]<=T` 进行剪枝,提高运行速度 + 总情况数为 $2^n$,时间复杂度为 $O(2^n)$。 ## 代码及解释 \ No newline at end of file diff --git a/1/solution2.md b/1/solution2.md deleted file mode 100644 index cdd2a21..0000000 --- a/1/solution2.md +++ /dev/null @@ -1,6 +0,0 @@ -## 思路 -使用 `dfs`,搜索每一件物品的选择情况,符合条件时输出。 - -使用 `sum+w[k]<=T` 进行剪枝,提高运行速度 - -## 代码及解释 \ No newline at end of file diff --git a/1/solution3.c b/1/solution3.c deleted file mode 100644 index 958f08d..0000000 --- a/1/solution3.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#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++; - if (solution_count > 50) - return; - 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; -} diff --git a/2/main.c b/2/main.c index efe2e4d..dfa5ff6 100644 --- a/2/main.c +++ b/2/main.c @@ -8,11 +8,34 @@ int re[16]; int xx[16]; int k = 0; -void pt(int state) { +void pt(int command, int state) { + int *f = malloc(sizeof(int) * 4); for (int i = 0; i < 4; i++) { - printf("%d ", (state >> i) & 1); + f[i] = (state >> i) & 1; + } + if (command == 0) { + printf("农夫自己过河\n"); + } else if (command == 1) { + printf("带 狼 过河\n"); + } else if (command == 2) { + printf("带 羊 过河\n"); + } else if (command == 3) { + printf("带 菜 过河\n"); + } + printf("A > "); + for (int i = 0; i < 4; i++) { + if (f[i] == 1) { + printf("%s ", labels[i]); + } } printf("\n"); + printf("B > "); + for (int i = 0; i < 4; i++) { + if (f[i] == 0) { + printf("%s ", labels[i]); + } + } + printf("\n---------------------\n"); } int validate_state(int state) { @@ -72,9 +95,8 @@ int trans(int x, int undo) { void dfs() { // printf(">> %d\n", state); if (state == 15) { - for(int i = 0; i < k; i++) { - printf("%d > ", xx[i]); - pt(re[i]); + for (int i = 0; i < k; i++) { + pt(xx[i], re[i]); } printf("\n"); return;