多重背包的二进制优化、单调栈二分dp

dp知识点:

多重背包的二进制优化:

本来是一个一个拆,再一个一个组成,现在将其变化为以二进制形式拆,再以二进制形式组成,以达成log级别

https://www.starrycoding.com/problem/76

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int M = 2e3 + 9;
int dp[M];
void solve() {
  int m, n;
  cin >> m >> n;
  for (int i = 1; i <= n; i++) {
    int s, w, v;
    cin >> s >> w >> v;
    vector<int> vec;
    int x = 1;
    while (s >= x) vec.push_back(x), s -= x, x <<= 1;
    if (s) vec.push_back(s);
    for (auto& k : vec) {
      for (int j = m; j >= 0; j--) {
        if (j >= k * v)
          dp[j] = max(dp[j], dp[j - k * v] + k * w);
        else
          dp[j] = dp[j];
      }
    }
  }
  cout << dp[m];
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

线性dp:

https://www.starrycoding.com/problem/77

暴力:O(N^2)

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int a[N], dp[N];

void solve() {
  int n;
  cin >> n;
  int max_n = 1;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= n; i++) {
    dp[i] = 1;
    for (int j = i - 1; j > 0; j--) {
      if (a[i] >= a[j]) dp[i] = max(dp[j] + 1, dp[i]);
      max_n = max(max_n, dp[i]);
    }
  }
  cout << max_n;
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

https://www.starrycoding.com/problem/48

运用栈将状态保存,不断优化最优位置

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int a[N];
int stk[N], top;
void solve() {
  int n;
  cin >> n;
  int ans = 0;
  for (int i = 1; i <= n; i++) cin >> a[i];
  for (int i = 1; i <= n; i++) {
    int pos = upper_bound(stk + 1, stk + 1 + top, a[i]) - stk;
    if (pos == top + 1) top++;
    stk[pos] = a[i];
    ans = max(ans, top);
  }
  cout << ans;
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

https://www.starrycoding.com/problem/78

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int a[N];
int stk[N], top;
void solve() {
  int ans = 0;
  int n = 0;
  while (cin >> a[++n]) {
  }
  n--;
  for (int i = 1; i <= n; i++) {
    int pos = upper_bound(stk + 1, stk + 1 + top, a[i],
                          [](const int& u, const int& v) { return u > v; }) -
              stk;
    if (pos == top + 1) top++;
    stk[pos] = a[i];
    ans = max(ans, top);
  }
  cout << ans << endl;
  top = 0, ans = 0;
  for (int i = 1; i <= n; i++) {
    int pos = lower_bound(stk + 1, stk + 1 + top, a[i]) - stk;
    if (pos == top + 1) top++;
    stk[pos] = a[i];
    ans = max(ans, top);
  }
  cout << ans;
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部