更新结构

This commit is contained in:
Luthics 2023-12-01 22:50:50 +08:00
parent ae8cb961fa
commit eb806421af
11 changed files with 118 additions and 183 deletions

View File

@ -1,3 +1,3 @@
30 10
9 6
10 10 8 6 6 5 10 8 4 1 8 4 3 5 2

View File

@ -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

33
1/dp.c Normal file
View File

@ -0,0 +1,33 @@
#include <stdio.h>
#include <stdlib.h>
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;
}

4
1/dp.in Normal file
View File

@ -0,0 +1,4 @@
70 3
71 100
69 1
1 2

47
1/dp.md Normal file
View File

@ -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 普及组第三题

View File

@ -25,6 +25,7 @@ void dfs(int t, int sum, int k) {
} }
printf("\n"); printf("\n");
} else if (sum < T && k < n) { } else if (sum < T && k < n) {
// 剪枝
if (sum + w[k] <= T) { if (sum + w[k] <= T) {
x[k] = 1; x[k] = 1;
dfs(t + 1, sum + w[k], k + 1); dfs(t + 1, sum + w[k], k + 1);
@ -36,7 +37,7 @@ void dfs(int t, int sum, int k) {
int main() { int main() {
freopen("data.in", "r", stdin); freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout); // freopen("data.out", "w", stdout);
scanf("%d", &T); scanf("%d", &T);
scanf("%d", &n); scanf("%d", &n);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {

View File

@ -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;
}

View File

@ -5,6 +5,8 @@
使用暴力 `dfs` 搜索,搜索每一件物品的选择情况,符合条件时输出。 使用暴力 `dfs` 搜索,搜索每一件物品的选择情况,符合条件时输出。
使用 `sum+w[k]<=T` 进行剪枝,提高运行速度
总情况数为 $2^n$,时间复杂度为 $O(2^n)$。 总情况数为 $2^n$,时间复杂度为 $O(2^n)$。
## 代码及解释 ## 代码及解释

View File

@ -1,6 +0,0 @@
## 思路
使用 `dfs`,搜索每一件物品的选择情况,符合条件时输出。
使用 `sum+w[k]<=T` 进行剪枝,提高运行速度
## 代码及解释

View File

@ -1,108 +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++;
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;
}

View File

@ -8,11 +8,34 @@ int re[16];
int xx[16]; int xx[16];
int k = 0; 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++) { 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("\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) { int validate_state(int state) {
@ -72,9 +95,8 @@ int trans(int x, int undo) {
void dfs() { void dfs() {
// printf(">> %d\n", state); // printf(">> %d\n", state);
if (state == 15) { if (state == 15) {
for(int i = 0; i < k; i++) { for (int i = 0; i < k; i++) {
printf("%d > ", xx[i]); pt(xx[i], re[i]);
pt(re[i]);
} }
printf("\n"); printf("\n");
return; return;