(DP) CF1861D Sorting By Multiplication

iscr發表於2024-06-29

題意:

思路:
考慮dp,設定dp[i][j]表示到i為止,處於j(0:上升段,1:下降段)所需要的最小運算元,然後在分情況dp即可。
唯一的一點需要注意,下降段不可能由上升段轉移過來,因為我要得到的是上升段,把上升段轉為下降段顯然不優,這部分不需要轉移。

code:

#include <bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using PII = pair<i64, i64>;
const int inf = 0x3f3f3f3f;
const i64 INF = 0x3f3f3f3f3f3f3f3f;
#define Z cout << "\n"
#define lb lower_bound
#define ub upper_bound
#define D(x) cerr << #x << ": " << (x) << "\n"
#define DV(v) cerr<<#v<<": ";for(int i=0;i<(v).size();i++)cerr<<((v)[i])<<",";cerr<<"\n"
#if 0
#define int i64
#endif
const int N = 2e5 + 5;
int dp[N][2];
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int>a(n + 5);
        for (int i = 1; i <= n; i++)cin >> a[i];
        for (int i = 1; i <= n; i++)dp[i][0] = dp[i][1] = inf;
        dp[1][0] = dp[1][1] = 1;
        for (int i = 2; i <= n; i++) {
            if (a[i] < a[i - 1]) {
                dp[i][0] = min(dp[i - 1][1], dp[i - 1][0]) + 1;
                dp[i][1] = dp[i - 1][1];
                // dp[i][1] = min(dp[i - 1][0] + 2, dp[i - 1][1]);
            }
            else if (a[i] == a[i - 1]) {
                dp[i][0] = min(dp[i - 1][1], dp[i - 1][0]) + 1;
                dp[i][1] = dp[i - 1][1] + 1;
                // dp[i][1] = min(dp[i - 1][0] + 2, dp[i - 1][1] + 1);
            }
            else {
                dp[i][0] = min(dp[i - 1][1] + 1, dp[i - 1][0]);
                dp[i][1] = dp[i - 1][1] + 1;
                //dp[i][1] = min(dp[i - 1][0] + 1, dp[i - 1][1] + 1);
            }
        }
        cout << min(dp[n][0] - 1, dp[n][1]) << "\n";
    }

    return 0;
}