状态压缩动态规划

This commit is contained in:
LittleSheep 2024-06-09 14:40:50 +08:00
parent 3f7ee8e8c0
commit 64a7875d1d
6 changed files with 100 additions and 9 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
*.bin
/cmake-build-debug
/.idea

24
CMakeLists.txt Normal file
View File

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.28)
project(Playground)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(Playground
complete-backup/main.cc
counting-people/main.cc
factorization/main.cc
fastest-way2unified-data/main.cc
flip-card/main.cc
jumping-wooden-trunk/main.cc
longest-decreasing-subsequence/main.cc
palindrome-number/main.cc
pick-class/main.cc
plug-dp/main.cc
reporting-number/main.cc
simple-calculator/main.cc
state-compress-dp/main.cpp
sudoku/main.cc
take-most-space-element/main.cc
walking-in-maze/main.cc)

View File

@ -4,16 +4,16 @@ using namespace std;
#define MAXN 10005
#define M 105
int dp[MAXN];
int w[M], v[M];
int w[M], state[M];
int x[M];
int main() {
int n, W;
cin >> W >> n;
for (int i = 1; i <= n; i++)
cin >> w[i] >> v[i];
cin >> w[i] >> state[i];
for (int i = 1; i <= n; i++)
for (int j = w[i]; j <= W; j++)
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
dp[j] = max(dp[j], dp[j - w[i]] + state[i]);
cout << dp[W] << endl;
return 0;
}

View File

@ -1,17 +1,17 @@
#include <iostream>
using namespace std;
const int MAXN = 105;
int dp[MAXN], arr[MAXN];
int dp[MAXN], obstacle[MAXN];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
cin >> obstacle[i];
dp[i] = n - 1;
}
dp[1] = 0;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= i + arr[i] && j <= n; j++) {
for (int j = i + 1; j <= i + obstacle[i] && j <= n; j++) {
dp[j] = min(dp[j], dp[i] + 1);
}
}

View File

@ -3,13 +3,13 @@ using namespace std;
#define MAXN 10005
#define M 200
int dp[MAXN];
int arr[M];
int obstacle[M];
int longest_decreasing_subsequence(int n) {
int maximun = 0;
for (int i = 0; i < n; i++) {
dp[i]++;
for (int j = 0; j < i; j++) {
if (arr[j] > arr[i]) // 最大上升为 `arr[j] < arr[i]`
if (obstacle[j] > obstacle[i]) // 最大上升为 `obstacle[j] < obstacle[i]`
dp[i] = max(dp[i], dp[j] + 1);
}
if (dp[i] > maximun)
@ -21,7 +21,7 @@ int main() {
int N;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> arr[i];
cin >> obstacle[i];
}
int value = longest_decreasing_subsequence(N);
cout << value << endl;

View File

@ -0,0 +1,64 @@
#include <iostream>
#include <vector>
using namespace std;
int m, n;
int obstacle[101];
int dp[101][1025];
const int MOD_FACTOR = 100000007;
vector<int> state;
void init_state() {
state.push_back(0);
for (int i = 0; i < (1 << n); i++) {
if (!(i & i << 1)) {
state.push_back(i);
}
}
}
void calculate() {
for (int j = 1; j < state.size(); j++) {
if (!(state[j] & obstacle[1])) { // Check overlap
dp[1][j] = 1;
}
}
for (int i = 2; i <= m; i++) {
for (int j = 1; j < state.size(); j++) {
if (!(state[j] & obstacle[i])) { // Check obstacle overlap
for (int k = 1; k < state.size(); k++) {
if (!(state[j] & state[k])) { // Check overlap
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD_FACTOR;
}
}
}
}
}
}
int main() {
cin >> m >> n;
for (int i = 1; i <= m; i++) {
obstacle[i] = 0;
int num;
for (int j = 1; j <= n; j++) {
cin >> num;
if (num == 0) {
obstacle[i] += (1 << (n - j));
}
}
}
init_state();
calculate();
int ans = 0;
for (int j = 1; j < state.size(); j++) {
ans = (ans + dp[m][j]) % MOD_FACTOR;
}
cout << ans - 1 << endl;
return 0;
}