diff --git a/.idea/editor.xml b/.idea/editor.xml
index 0fea8c4..f86872e 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -230,7 +230,7 @@
-
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 7cf4251..1108cee 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,7 @@
-
+
@@ -21,54 +21,84 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -100,6 +130,9 @@
+
+
+
@@ -128,6 +161,7 @@
"C/C++ 文件.luogu_UVA755.cpp.executor": "Run",
"C/C++ 文件.luogu_ez_B3628.cpp.executor": "Run",
"C/C++ 文件.luogu_model_dsu_P3367.cpp.executor": "Run",
+ "C/C++ 文件.noip2003j_bigint.cpp.executor": "Run",
"C/C++ 文件.ojcs101_E01003.cpp.executor": "Run",
"C/C++ 文件.ojcs101_E01218.cpp.executor": "Run",
"C/C++ 文件.ojcs101_E02883.cpp.executor": "Run",
@@ -145,13 +179,25 @@
"C/C++ 文件.pojcs101_M02694_polish_notation_tree.cpp.executor": "Run",
"C/C++ 文件.pojcs101_M03247_palindromic_prime.cpp.executor": "Run",
"C/C++ 文件.pojcs101_M03441_sum_zero.cpp.executor": "Run",
+ "CMake 应用程序.NOIP2005J_herbs_dp_backpack.executor": "Run",
+ "CMake 应用程序.NOIP2005J_herbs_dp_backpack_MWASTE_BETTER.executor": "Run",
+ "CMake 应用程序.NOIP2006S_jinming_budget_dp_knapsack.executor": "Run",
+ "CMake 应用程序.SHOI2002_ski_dp.executor": "Run",
"CMake 应用程序.exercises.executor": "Run",
+ "CMake 应用程序.gdbh.executor": "Run",
"CMake 应用程序.lc_135_candy.executor": "Run",
+ "CMake 应用程序.luogu_P2196_miner_dp.executor": "Run",
+ "CMake 应用程序.noip2003j_bigint.executor": "Run",
"CMake 应用程序.pojcs101_M02694_polish_notation_tree.executor": "Run",
"CMake 应用程序.pojcs101_M03441_sum_zero.executor": "Run",
"CMake 应用程序.pojcs101_M03532.executor": "Run",
"CMake 应用程序.pojcs101_M03704_brackets.executor": "Run",
"CMake 应用程序.pojcs101_T01011_sticks.executor": "Run",
+ "CMake 应用程序.pojcs101_T04117_split_int.executor": "Run",
+ "CMake 应用程序.pojcs101_T12559_biggest_smallest_combination.executor": "Run",
+ "CMake 应用程序.pojcs101_T27104_chicken_monitors.executor": "Run",
+ "CMake 应用程序.pojcs101_T27373_biggest_combination_t2.executor": "Run",
+ "CMake 应用程序.test.executor": "Run",
"CMake 调试.exercises.executor": "Debug",
"CidrDebugProfileConversion": "true",
"ModuleVcsDetector.initialDetectionPerformed": "true",
@@ -170,20 +216,26 @@
"codeWithMe.voiceChat.enabledByDefault": "false",
"deletionFromPopupRequiresConfirmation": "false",
"git-widget-placeholder": "main",
- "last_opened_file_path": "/Users/roger/coding/exercises",
+ "last_opened_file_path": "/Users/roger/coding/exercises/dp/backpack_dp",
"node.js.detected.package.jshint": "true",
"node.js.selected.package.jshint": "",
"nodejs_package_manager_path": "npm",
"org.rust.first.attach.projects": "true",
- "settings.editor.selected.configurable": "CPPToolchains"
+ "settings.editor.selected.configurable": "editor.preferences.completion.inline"
}
}]]>
+
+
+
+
+
+
-
+
@@ -209,7 +261,77 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -259,16 +381,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -359,6 +471,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -410,36 +552,54 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
@@ -450,6 +610,32 @@
+
@@ -482,9 +668,9 @@
-
-
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 71a0fbe..43fec66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,15 +1,29 @@
cmake_minimum_required(VERSION 3.10)
project(exercises)
-# 设置 C++ 标准(例如 C++17)
set(CMAKE_CXX_STANDARD 17)
-# 递归查找当前目录下所有的 .cpp 文件
file(GLOB_RECURSE SOURCES "*.cpp")
-# 遍历所有找到的 .cpp 文件,为每个文件单独创建一个可执行目标
foreach (source ${SOURCES})
- # 获取文件名(不带扩展名)作为可执行文件的名字
+ # 获取源文件所在目录(绝对路径)
+ get_filename_component(dir ${source} DIRECTORY)
+ # 计算相对于源码根目录的路径
+ file(RELATIVE_PATH rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir})
+ # 获取文件名(不带扩展名)
get_filename_component(name ${source} NAME_WE)
- add_executable(${name} ${source})
+
+ # 构造带相对路径的目标名,例如 src_utils_foo
+ if (rel_dir STREQUAL "")
+ set(target_name "${name}")
+ else ()
+ string(REPLACE "/" "__" rel_dir_flat "${rel_dir}")
+ set(target_name "${rel_dir_flat}__${name}")
+ endif ()
+
+ add_executable(${target_name} ${source})
+ # 顺便把可执行文件输出到与源文件对应的目录中(可选)
+ set_target_properties(${target_name} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${rel_dir}"
+ )
endforeach ()
\ No newline at end of file
diff --git a/NOIP2003J_bigint.cpp b/NOIP2003J_bigint.cpp
new file mode 100644
index 0000000..576b48f
--- /dev/null
+++ b/NOIP2003J_bigint.cpp
@@ -0,0 +1,104 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+/// 只处理 500 位!
+class BigInt {
+public:
+ using bigint = vector;
+ static constexpr unsigned int BASE_DIGITS = 8;
+ const unsigned long long BASE = static_cast(std::pow(10, BASE_DIGITS));
+ static constexpr size_t TARGET_SIZE = 125;
+ bigint value;
+
+ BigInt() : value({0}) { organize(); }
+ BigInt(bigint v) : value(std::move(v)) { organize(); }
+
+ BigInt(unsigned long long v) {
+ value.push_back(v);
+ organize();
+ }
+
+ void organize() {
+ value.resize(TARGET_SIZE, 0);
+ for (int i = 0; i < TARGET_SIZE - 1; i++) {
+ value[i + 1] += value[i] / BASE;
+ value[i] %= BASE;
+ }
+ value[TARGET_SIZE - 1] %= BASE;
+ }
+
+ BigInt& operator=(const BigInt& other) {
+ value = other.value;
+ organize();
+ return *this;
+ }
+
+ BigInt operator*(const BigInt& other) const {
+ BigInt ans(0);
+ for (int i = 0; i < TARGET_SIZE; i++) {
+ for (int j = 0; i + j < TARGET_SIZE; j++) {
+ ans.value[i + j] += value[i] * other.value[j];
+ }
+ }
+ ans.organize();
+ return ans;
+ }
+
+ BigInt operator*(const unsigned long other) const {
+ BigInt ans(*this);
+ ans.value[0] *= other;
+ ans.organize();
+ return ans;
+ }
+
+ template
+ BigInt operator*=(const T& other) {
+ *this = *this * other;
+ return *this;
+ }
+
+
+ [[nodiscard]] BigInt pow(unsigned int exp) const {
+ if (exp == 0) { return {1}; }
+ if (exp == 1) { return *this; }
+ BigInt ans = (*this * *this).pow(exp / 2);
+ if (exp % 2 == 1) {
+ ans *= *this;
+ }
+ return ans;
+ }
+
+ [[nodiscard]] string to_string(size_t digits = 500) const {
+ string s;
+ for (int i = 0; i < TARGET_SIZE; i++) {
+ string current = std::to_string(value[i]);
+ if (current.size() < BASE_DIGITS) {
+ current.insert(0, BASE_DIGITS - current.size(), '0');
+ }
+ s.insert(0, current);
+ }
+ return s.substr(s.size() - digits, s.size());
+ }
+};
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ unsigned int exp;
+ cin >> exp;
+ cout << floor(exp * log10(2)) + 1 << endl;
+ BigInt ans = BigInt(2).pow(exp);
+ ans.value[0] -= 1; // 2^n 没问题
+ string s = ans.to_string(500);
+ for (int i = 0; i < 500; i += 50) {
+ cout << s.substr(i, 50) << endl;
+ }
+
+
+ return 0;
+}
diff --git a/pojcs101_M01088_ski.cpp b/SHOI2002_ski.cpp
similarity index 100%
rename from pojcs101_M01088_ski.cpp
rename to SHOI2002_ski.cpp
diff --git a/pojcs101_M01088_ski_WRONG.cpp b/SHOI2002_ski_WRONG.cpp
similarity index 100%
rename from pojcs101_M01088_ski_WRONG.cpp
rename to SHOI2002_ski_WRONG.cpp
diff --git a/_others/qyz/gdbh.cpp b/_others/qyz/gdbh.cpp
new file mode 100644
index 0000000..b28f11b
--- /dev/null
+++ b/_others/qyz/gdbh.cpp
@@ -0,0 +1,43 @@
+#include
+
+using namespace std;
+
+int primes[2001];
+
+bool is_prime(int a) {
+ for (int i = 2; i * i <= a; i++) {
+ if (a % i != 0) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void init_primes() {
+ int current_num = 2, i = 0;
+ for (;; current_num++) {
+ if (is_prime(current_num)) {
+ primes[i] = current_num;
+ i++;
+ }
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+ int a;
+ cin >> a;
+ if (a % 2 != 0 || a < 6) {
+ cout << "Error!" << endl;
+ } else
+ for (int i = 0; primes[i] <= a / 2; i++) {
+ if (is_prime(a - primes[i])) {
+ cout << a << "=" << i << "+" << a - i << endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/_others/qyz/test.cpp b/_others/qyz/test.cpp
new file mode 100644
index 0000000..8d6ba74
--- /dev/null
+++ b/_others/qyz/test.cpp
@@ -0,0 +1,18 @@
+#include
+
+using namespace std;
+
+
+// x[0]..x[99]
+
+bool is_prime(int n) {
+ for (int i=2; i*i<=n; i++) {
+ if (n%i == 0) {return false;}
+ }
+ return true;
+}
+
+int main() {
+ cout << is_prime(4);
+ return 0;
+}
\ No newline at end of file
diff --git a/dp/NOIP1996S_miner_dp.cpp b/dp/NOIP1996S_miner_dp.cpp
new file mode 100644
index 0000000..457d609
--- /dev/null
+++ b/dp/NOIP1996S_miner_dp.cpp
@@ -0,0 +1,84 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+struct Node {
+ int mine_amount = -1, prev = -1;
+};
+
+constexpr int MAX_N = 25, INF = 0x3f3f3f3f;
+int n, mine_amounts[MAX_N];
+bool adj[MAX_N][MAX_N];
+
+// int dp[MAX_N][MAX_N];
+Node dp_route[MAX_N];
+
+void solve_dp() {
+ for (int i=0; i dp_route[current].mine_amount) {
+ dp_route[current] = {.mine_amount = new_ans, .prev = prev};
+ }
+ }
+ }
+ }
+}
+
+void print_route() {
+ int max_ans = -1, max_idx = -1;
+ vector final_route;
+ for (int i = 0; i < n; i++) {
+ if (dp_route[i].mine_amount > max_ans) {
+ max_ans = dp_route[i].mine_amount;
+ max_idx = i;
+ }
+ }
+ while (max_idx != -1) {
+ final_route.push_back(max_idx);
+ max_idx = dp_route[max_idx].prev;
+ }
+ reverse(final_route.begin(), final_route.end());
+ for (const int i : final_route) {
+ cout << i + 1 << " ";
+ }
+ cout << endl << max_ans << endl;
+}
+
+void log_dp() {
+ for (int i = 0; i < n; i++) {
+ // for (int j = 0; j < n; j++) {
+ // clog << dp[i][j] << " ";
+ // }
+ clog << "->" << dp_route[i].mine_amount << " " << dp_route[i].prev << endl;
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> mine_amounts[i];
+ }
+ for (int i = 0; i < n; i++) {
+ for (int j = i + 1; j < n; j++) {
+ cin >> adj[i][j];
+ adj[j][i] = adj[i][j];
+ }
+ }
+
+ solve_dp();
+ log_dp();
+ print_route();
+
+ return 0;
+}
diff --git a/dp/NOIP1996S_miner_dp_MWASTE.cpp b/dp/NOIP1996S_miner_dp_MWASTE.cpp
new file mode 100644
index 0000000..003cd04
--- /dev/null
+++ b/dp/NOIP1996S_miner_dp_MWASTE.cpp
@@ -0,0 +1,85 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+struct Node {
+ int mine_amount = -1, prev = -1;
+};
+
+constexpr int MAX_N = 25, INF = 0x3f3f3f3f;
+int n, mine_amounts[MAX_N];
+bool adj[MAX_N][MAX_N];
+
+int dp[MAX_N][MAX_N];
+Node dp_route[MAX_N];
+
+void solve_dp() {
+ memset(dp, -1, sizeof(dp));
+ for (int i=0; i dp_route[current].mine_amount) {
+ dp_route[current] = {.mine_amount = dp[current][prev], .prev = prev};
+ }
+ }
+ }
+ }
+}
+
+void print_route() {
+ int max_ans = -1, max_idx = -1;
+ vector final_route;
+ for (int i = 0; i < n; i++) {
+ if (dp_route[i].mine_amount > max_ans) {
+ max_ans = dp_route[i].mine_amount;
+ max_idx = i;
+ }
+ }
+ while (max_idx != -1) {
+ final_route.push_back(max_idx);
+ max_idx = dp_route[max_idx].prev;
+ }
+ reverse(final_route.begin(), final_route.end());
+ for (const int i : final_route) {
+ cout << i + 1 << " ";
+ }
+ cout << endl << max_ans << endl;
+}
+
+void log_dp() {
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ clog << dp[i][j] << " ";
+ }
+ clog << "->" << dp_route[i].mine_amount << " " << dp_route[i].prev << endl;
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> mine_amounts[i];
+ }
+ for (int i = 0; i < n; i++) {
+ for (int j = i + 1; j < n; j++) {
+ cin >> adj[i][j];
+ adj[j][i] = adj[i][j];
+ }
+ }
+
+ solve_dp();
+ log_dp();
+ print_route();
+
+ return 0;
+}
diff --git a/dp/SHOI2002_ski_dp.cpp b/dp/SHOI2002_ski_dp.cpp
new file mode 100644
index 0000000..d2aeb84
--- /dev/null
+++ b/dp/SHOI2002_ski_dp.cpp
@@ -0,0 +1,110 @@
+#include
+#include
+#include
+
+using namespace std;
+
+struct Node {
+ int x, y, height;
+};
+
+constexpr int MAX_N = 105;
+constexpr short DX[4] = {0, 1, 0, -1}, DY[4] = {1, 0, -1, 0};
+int r, c;
+int heights[MAX_N][MAX_N];
+vector adj_nodes[MAX_N * MAX_N];
+vector nodes;
+
+int dp[MAX_N * MAX_N];
+
+int pack_coord(int x, int y) {
+ return x * c + y;
+}
+
+int pack_coord(Node node) {
+ return pack_coord(node.x, node.y);
+}
+
+bool within_board(int x, int y) {
+ return 0 <= x && x < r && 0 <= y && y < c;
+}
+
+
+void log_dp() {
+ for (int i = 0; i < r * c; i++) {
+ clog << dp[i] << "\t";
+ if (i % c == c - 1) {
+ clog << endl;
+ }
+ }
+}
+
+void log_adj_nodes() {
+ for (int i = 0; i < r * c; i++) {
+ clog << i << " -> ";
+ for (int adj_node : adj_nodes[i]) {
+ clog << adj_node << " ";
+ }
+ clog << endl;
+ }
+}
+
+void init_adj_nodes() {
+ for (int i = 0; i < r; i++) {
+ for (int j = 0; j < c; j++) {
+ nodes.push_back({i, j, heights[i][j]});
+ int x = i, y = j;
+ for (int k = 0; k < 4; k++) {
+ int nx = x + DX[k], ny = y + DY[k];
+ if (within_board(nx, ny) && heights[nx][ny] > heights[x][y]) {
+ // 反向建图,小 -> 大
+ adj_nodes[pack_coord(x, y)].push_back(pack_coord(nx, ny));
+ }
+ }
+ }
+ }
+ sort(nodes.begin(), nodes.end(), [](const Node& a, const Node& b) {
+ return a.height > b.height;
+ });
+}
+
+
+void solve_dp() {
+ dp[pack_coord(nodes[0])] = 1;
+ for (int i = 1; i < nodes.size(); i++) {
+ Node curr_node = nodes[i];
+ int max_dp = 0;
+ for (int adj_node : adj_nodes[pack_coord(curr_node)]) {
+ max_dp = max(max_dp, dp[adj_node]);
+ }
+ dp[pack_coord(curr_node)] = max_dp + 1;
+ }
+}
+
+int get_ans() {
+ int max_dp = -1;
+ for (int i = 0; i < r * c; i++) {
+ max_dp = max(max_dp, dp[i]);
+ }
+ return max_dp;
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> r >> c;
+ for (int i = 0; i < r; i++) {
+ for (int j = 0; j < c; j++) {
+ cin >> heights[i][j];
+ }
+ }
+
+ init_adj_nodes();
+ solve_dp();
+ log_adj_nodes();
+ log_dp();
+ cout << get_ans() << endl;
+
+ return 0;
+}
diff --git a/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack.cpp b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack.cpp
new file mode 100644
index 0000000..366d076
--- /dev/null
+++ b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack.cpp
@@ -0,0 +1,52 @@
+#include
+
+using namespace std;
+
+struct Item {
+ int weight, value;
+};
+
+constexpr int MAX_N = 105, MAX_CAPACITY = 1005;
+int capacity, n;
+Item items[MAX_N];
+int dp[MAX_CAPACITY];
+bool ping_pong;
+
+void log_dp() {
+ // for (int i = 0; i <= 1; i++) {
+ for (int j = 0; j <= capacity; j++) {
+ clog << dp[j] << "\t";
+ }
+ clog << endl;
+ // }
+}
+
+void solve_dp() {
+ // for (int i = 0; i <= capacity; i++) { dp[0][i] = 0; }
+ // for (int i = 0; i <= n; i++) { dp[i][0] = 0; }
+ for (int stop_item = 1; stop_item <= n; stop_item++, ping_pong = !ping_pong) {
+ for (int w = capacity; w >= 1; w--) {
+ if (w >= items[stop_item - 1].weight) { // 负数
+ dp[w] = max(dp[w],
+ dp[w - items[stop_item - 1].weight] + items[stop_item - 1].value);
+ }
+ }
+ // log_dp();
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> capacity >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> items[i].weight >> items[i].value;
+ }
+
+ solve_dp();
+ cout << dp[capacity] << endl;
+
+
+ return 0;
+}
diff --git a/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE.cpp b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE.cpp
new file mode 100644
index 0000000..31d5961
--- /dev/null
+++ b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE.cpp
@@ -0,0 +1,48 @@
+/*
+ * 背包 DP:考虑前 i 个物品的最大价值,在仅有 t 容量的情况下。
+ * 建议两个维度调换一下,方便乒乓/滚动。
+ */
+
+#include
+
+using namespace std;
+
+struct Item {
+ int weight, value;
+};
+
+constexpr int MAX_N = 105, MAX_CAPACITY = 1005;
+int capacity, n;
+Item items[MAX_N];
+int dp[MAX_CAPACITY][MAX_N];
+
+void solve_dp() {
+ for (int i = 0; i <= capacity; i++) { dp[i][0] = 0; }
+ for (int i = 0; i <= n; i++) { dp[0][i] = 0; }
+ for (int stop_item = 1; stop_item <= n; stop_item++) {
+ for (int w = 1; w <= capacity; w++) {
+ dp[w][stop_item] = dp[w][stop_item - 1];
+ if (w >= items[stop_item - 1].weight) { // 负数
+ dp[w][stop_item] =
+ max(dp[w][stop_item],
+ dp[w - items[stop_item - 1].weight][stop_item - 1] + items[stop_item - 1].value);
+ }
+ }
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> capacity >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> items[i].weight >> items[i].value;
+ }
+
+ solve_dp();
+ cout << dp[capacity][n] << endl;
+
+
+ return 0;
+}
diff --git a/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE_BETTER.cpp b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE_BETTER.cpp
new file mode 100644
index 0000000..fba2ec2
--- /dev/null
+++ b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_MWASTE_BETTER.cpp
@@ -0,0 +1,57 @@
+/*
+* 背包 DP:考虑前 i 个物品的最大价值,在仅有 t 容量的情况下。
+ */
+
+#include
+
+using namespace std;
+
+struct Item {
+ int weight, value;
+};
+
+constexpr int MAX_N = 105, MAX_CAPACITY = 1005;
+int capacity, n;
+Item items[MAX_N];
+int dp[MAX_N][MAX_CAPACITY];
+
+void log_dp() {
+ for (int i = 0; i <= n; i++) {
+ for (int j = 0; j <= capacity; j++) {
+ clog << dp[i][j] << "\t";
+ }
+ clog << endl;
+ }
+}
+
+void solve_dp() {
+ for (int i = 0; i <= capacity; i++) { dp[0][i] = 0; }
+ for (int i = 0; i <= n; i++) { dp[i][0] = 0; }
+ for (int stop_item = 1; stop_item <= n; stop_item++) {
+ for (int w = 1; w <= capacity; w++) {
+ dp[stop_item][w] = dp[stop_item - 1][w];
+ if (w >= items[stop_item - 1].weight) { // 负数
+ dp[stop_item][w] =
+ max(dp[stop_item][w],
+ dp[stop_item - 1][w - items[stop_item - 1].weight] + items[stop_item - 1].value);
+ }
+ }
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> capacity >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> items[i].weight >> items[i].value;
+ }
+
+ solve_dp();
+ log_dp();
+ cout << dp[n][capacity] << endl;
+
+
+ return 0;
+}
\ No newline at end of file
diff --git a/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_PINGPONG.cpp b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_PINGPONG.cpp
new file mode 100644
index 0000000..9da63a0
--- /dev/null
+++ b/dp/backpack_dp/NOIP2005J_herbs_dp_knapsack_PINGPONG.cpp
@@ -0,0 +1,54 @@
+#include
+
+using namespace std;
+
+struct Item {
+ int weight, value;
+};
+
+constexpr int MAX_N = 105, MAX_CAPACITY = 1005;
+int capacity, n;
+Item items[MAX_N];
+int dp[2][MAX_CAPACITY];
+bool ping_pong;
+
+void log_dp() {
+ // for (int i = 0; i <= 1; i++) {
+ for (int j = 0; j <= capacity; j++) {
+ clog << dp[ping_pong][j] << "\t";
+ }
+ clog << endl;
+ // }
+}
+
+void solve_dp() {
+ // for (int i = 0; i <= capacity; i++) { dp[0][i] = 0; }
+ // for (int i = 0; i <= n; i++) { dp[i][0] = 0; }
+ for (int stop_item = 1; stop_item <= n; stop_item++, ping_pong = !ping_pong) {
+ for (int w = 1; w <= capacity; w++) {
+ dp[ping_pong][w] = dp[!ping_pong][w];
+ if (w >= items[stop_item - 1].weight) { // 负数
+ dp[ping_pong][w] =
+ max(dp[ping_pong][w],
+ dp[!ping_pong][w - items[stop_item - 1].weight] + items[stop_item - 1].value);
+ }
+ }
+ // log_dp();
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> capacity >> n;
+ for (int i = 0; i < n; i++) {
+ cin >> items[i].weight >> items[i].value;
+ }
+
+ solve_dp();
+ cout << dp[!ping_pong][capacity] << endl;
+
+
+ return 0;
+}
\ No newline at end of file
diff --git a/dp/backpack_dp/NOIP2006S_jinming_budget_dp_knapsack.cpp b/dp/backpack_dp/NOIP2006S_jinming_budget_dp_knapsack.cpp
new file mode 100644
index 0000000..596118b
--- /dev/null
+++ b/dp/backpack_dp/NOIP2006S_jinming_budget_dp_knapsack.cpp
@@ -0,0 +1,86 @@
+#include
+#include
+
+using namespace std;
+
+struct FlatItem {
+ int weight, value;
+
+ FlatItem operator+(const FlatItem& other) const {
+ return {.weight = weight + other.weight, .value = value + other.value};
+ }
+};
+
+struct OriginalItem {
+ FlatItem item{};
+ vector sons;
+};
+
+constexpr int MAX_N = 65, MAX_CAPACITY = 32005;
+
+int capacity, n;
+vector items;
+vector flat_items;
+int fathers_temp[MAX_N];
+
+int dp[MAX_CAPACITY];
+
+vector generate_flat_items(OriginalItem item) {
+ switch (item.sons.size()) {
+ case 0:
+ return vector{item.item};
+ case 1:
+ return vector{
+ item.item,
+ item.sons[0] + item.item,
+ };
+ case 2:
+ return vector{
+ item.item,
+ item.sons[0] + item.item,
+ item.sons[1] + item.item,
+ item.sons[0] + item.sons[1] + item.item,
+ };
+ default:
+ throw logic_error("Invalid item size!");
+ }
+}
+
+
+void solve_dp() {
+ for (int i = 0; i < n; i++) {
+ if (items[i].item.value == -1) { continue; }
+ for (int w=capacity; w>=1; w--) {
+ // dp[w] = dp[w] // 不买
+ for (const auto& [weight, value] : generate_flat_items(items[i])) {
+ if (w >= weight) {
+ dp[w] = max(dp[w], dp[w - weight] + value);
+ }
+ }
+ }
+ }
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ cin >> capacity >> n;
+ items.resize(n);
+
+ for (int i = 0; i < n; i++) {
+ cin >> items[i].item.weight >> items[i].item.value >> fathers_temp[i];
+ items[i].item.value *= items[i].item.weight; // 题意
+ }
+ for (int i = 0; i < n; i++) {
+ if (fathers_temp[i] != 0) {
+ items[fathers_temp[i] - 1].sons.push_back(items[i].item);
+ items[i].item.value = -1; // 删掉这个元素!
+ }
+ }
+
+ solve_dp();
+ cout << dp[capacity] << endl;
+
+ return 0;
+}
diff --git a/pojcs101_T04117_split_int.cpp b/pojcs101_T04117_split_int.cpp
new file mode 100644
index 0000000..7a2d246
--- /dev/null
+++ b/pojcs101_T04117_split_int.cpp
@@ -0,0 +1,39 @@
+#include
+#include
+
+using namespace std;
+
+constexpr int MAX_N = 100;
+int cache[MAX_N * MAX_N];
+
+int get_split_solutions_count(int n, int parts_count) {
+ if (n <= 0 || parts_count > n) { return 0; }
+ if (parts_count == 1 || parts_count == n) { return 1; }
+ if (cache[n * MAX_N + parts_count] != 0) {
+ return cache[n * MAX_N + parts_count];
+ }
+ int ans = 0;
+ for (int i = 1; i <= n / 2; i++) {
+ ans += get_split_solutions_count(n - i - (i - 1) * (parts_count - 1), parts_count - 1);
+ }
+ cache[n * MAX_N + parts_count] = ans;
+ return ans;
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ int n;
+ while (cin >> n) {
+ // cout << get_split_solutions_count(n, 2) << endl;
+ int ans = 0;
+ for (int i = 1; i <= n; i++) {
+ ans += get_split_solutions_count(n, i);
+ // clog << i << ":" << ans << " ";
+ }
+ cout << ans << endl;
+ }
+
+ return 0;
+}
diff --git a/pojcs101_T12559_biggest_smallest_combination.cpp b/pojcs101_T12559_biggest_smallest_combination.cpp
new file mode 100644
index 0000000..28af504
--- /dev/null
+++ b/pojcs101_T12559_biggest_smallest_combination.cpp
@@ -0,0 +1,32 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ int nums_amount;
+ cin >> nums_amount;
+ vector nums(nums_amount);
+ for (int i = 0; i < nums_amount; i++) {
+ cin >> nums[i];
+ }
+ sort(nums.begin(), nums.end(), [](const string& a, const string& b) {
+ return a + b < b + a;
+ });
+ for (int i = nums_amount - 1; i >= 0; i--) {
+ cout << nums[i];
+ }
+ cout << " ";
+ for (int i = 0; i < nums_amount; i++) {
+ cout << nums[i];
+ }
+ cout << endl;
+
+ return 0;
+}
diff --git a/pojcs101_T12559_biggest_smallest_combination_WRONG.cpp b/pojcs101_T12559_biggest_smallest_combination_WRONG.cpp
new file mode 100644
index 0000000..af9b993
--- /dev/null
+++ b/pojcs101_T12559_biggest_smallest_combination_WRONG.cpp
@@ -0,0 +1,66 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+size_t get_digits(unsigned long long number) {
+ return static_cast(log10(number)) + 1;
+}
+
+bool is_number_rising(unsigned long long number) {
+ while (number % 10 == (number / 10) % 10) { number /= 10; }
+ return (number / 10) % 10 < number % 10;
+}
+
+struct PartialNumber {
+ unsigned long long number = 0;
+ unsigned long long filled_number = -1;
+ size_t digits = 0;
+
+ void fill() {
+ digits = get_digits(number);
+ filled_number = number;
+ while (filled_number < 10000000000000000) {
+ filled_number *= 10, filled_number += number % 10;
+ }
+ }
+
+ bool operator<(PartialNumber& other) {
+ if (filled_number == -1) { fill(); }
+ if (other.filled_number == -1) { other.fill(); }
+ if (filled_number == other.filled_number) {
+ if (is_number_rising(number)) { return digits < other.digits; }
+ return digits > other.digits;
+ }
+ return filled_number < other.filled_number;
+ }
+
+ bool operator>(PartialNumber& other) {
+ return other < *this;
+ }
+};
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ int nums_amount;
+ cin >> nums_amount;
+ vector nums(nums_amount);
+ for (int i = 0; i < nums_amount; i++) {
+ cin >> nums[i].number;
+ }
+ sort(nums.begin(), nums.end());
+ for (int i = nums_amount - 1; i >= 0; i--) {
+ cout << nums[i].number;
+ }
+ cout << " ";
+ for (int i = 0; i < nums_amount; i++) {
+ cout << nums[i].number;
+ }
+ cout << endl;
+
+ return 0;
+}
diff --git a/pojcs101_T27104_chicken_monitors.cpp b/pojcs101_T27104_chicken_monitors.cpp
new file mode 100644
index 0000000..7b16feb
--- /dev/null
+++ b/pojcs101_T27104_chicken_monitors.cpp
@@ -0,0 +1,62 @@
+#include
+#include
+#include
+
+using namespace std;
+
+using Range = pair;
+
+void log_range_vector(const vector& ranges, const string& prefix = "") {
+ clog << prefix;
+ for (const Range& r : ranges) {
+ clog << "(" << r.first << "," << r.second << ")" << " ";
+ }
+ clog << endl;
+}
+
+size_t get_min_ranges_amount(vector ranges, Range full_range) {
+ sort(ranges.begin(), ranges.end());
+ log_range_vector(ranges, "ranges: ");
+ size_t i = 0, ans = 0;
+ while (ranges[i].second < full_range.first) { i++; }
+ int max_start = 0, current_end = ranges[i].second;
+ while (true) {
+ while (ranges[i].first <= max_start) {
+ current_end = max(current_end, ranges[i].second);
+ if (current_end >= full_range.second) { return ans + 1; }
+ i++;
+ if (i >= ranges.size()) { throw invalid_argument("No valid ranges found (inside loop)"); }
+ }
+ ans++;
+ if (current_end >= full_range.second) { return ans; }
+ max_start = current_end;
+ }
+ throw invalid_argument("No valid ranges found (outside loop)");
+}
+
+vector get_ranges(const vector& monitors) {
+ vector ranges;
+ for (int i = 0; i < monitors.size(); i++) {
+ ranges.emplace_back(i - monitors[i], i + monitors[i] + 1);
+ }
+ return ranges;
+}
+
+int main() {
+ ios::sync_with_stdio(false);
+ cin.tie(nullptr);
+
+ size_t monitors_amount;
+ cin >> monitors_amount;
+ vector monitors(monitors_amount);
+ for (int i = 0; i < monitors_amount; i++) {
+ cin >> monitors[i];
+ }
+ vector ranges = get_ranges(monitors);
+ Range full_range = {0, monitors_amount};
+
+ cout << get_min_ranges_amount(ranges, full_range) << endl;
+
+
+ return 0;
+}
diff --git a/pojcs101_T27373_biggest_combination_t2.cpp b/pojcs101_T27373_biggest_combination_t2.cpp
new file mode 100644
index 0000000..1786c47
--- /dev/null
+++ b/pojcs101_T27373_biggest_combination_t2.cpp
@@ -0,0 +1,59 @@
+#include
+#include
+#include