Dec. 27th 2025

Dec. 27th 2025

周测


[POI 2013] BAJ-Bytecomputer

DP\(\lor\)贪心

  1. 贪心:

    明确事实:数字 \(0\) 对于序列没有任何作用,开头的数无法改变

    先考虑无解的情况

    E.g a[] = {0, 0, -1, -1, 1, -1}

    发现在开头都是一段 \(0\) 时若第一个非 \(0\) 位置为 \(-1\) ,则此时无论如何都不可能满足非递减的情况(\(0\to -1\) 已经递减,而一连串的 \(0\) 对序列无用)

    然后考虑最终解的形式:一定是有序多重集合 \(\{n_{-1} \times -1, n_0 \times 0, n_1 \times 1\}\) ,其中:\(0\le n_{-1},n_0,n_1\)

    因为修改成不属于 \(\{-1,0,1\}\) 的形式一定会消耗更多的步数

    考虑不同数开头的情况

    • \(1\) 开头:因为开头无法修改,所以后面只能够变成 \(1\)
    • \(0\) 开头:化归成上一个情况;
    • \(-1\)自己推,考虑变化的情况

    代码

    #include <bits/stdc++.h>
    using namespace std;
    using lf = double;
    using ll = long long;
    using ull = unsigned long long;
    const int maxn = 1e6 + 5;
    const int INF = INT_MAX / 3;
    int n, arr[maxn], suff[maxn], nxt[maxn], posi;
    void solve() {
    	cin >> n;
    	posi = n + 1; // 零的位置
    	for (int i = 1; i <= n; i++) cin >> arr[i];
    	for (int i = n; i >= 1; i--) {
    		suff[i] = suff[i + 1] + (1 - arr[i]); // 数列 {1-a_i} 的后缀和
    		nxt[i] = posi;
    		if (arr[i]) posi = i;
    	}
    	if (arr[1] == 1) {
    		cout << suff[1] << "\n";
    		exit(0);
    	}
    	if (arr[1] == 0) {
    		if (arr[nxt[1]] == -1){
    			cout << "BRAK\n";
    			exit(0);
    		}
    		cout << suff[nxt[1]] << "\n";
    		exit(0);
    	}
    	int ans = INF, tot = 0;
    	for (int i = 1; i <= n; i++) {
    		tot += arr[i] + 1;
    		if (arr[nxt[i]] != -1) ans = min(ans, tot + suff[nxt[i]]);
    		if (i < n /*如果不是结尾*/ and arr[i + 1] == 1 /*a[n] == 1*/) ans = min(ans, tot + 1 + suff[nxt[i + 1]]);
    	}
    	cout << ans << "\n";
    }
    
    int main() {
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int T = 1;
    	while (T--) solve();
    }
    
    1. DP

      式子:

      \[\text{dp}_{i,0} = \begin{cases} \text{dp}_{i-1,0}+2 \ \ \text{if } \text{arr}_i = 1 \\ \text{dp}_{i-1,0}+1 \ \ \text{if } \text{arr}_i = 0 \\ \text{dp}_{i-1,0} \ \ \text{if } \text{arr}_i = -1 \end{cases} \\ \text{dp}_{i,1} = \begin{cases} \text{dp}_{i-1,0}+1 \ \ \text{if } \text{arr}_i = 1 \\ \min(\text{dp}_{i-1,0}, \text{dp}_{i-1,1}) \ \ \text{if } \text{arr}_i = 0 \\ \text{none} \ \ \text{if } \text{arr}_i = -1 \end{cases} \\ \text{dp}_{i,2} = \begin{cases} \min\{\text{dp}_{i-1,0},\text{dp}_{i-1,1}, \text{dp}_{i-1,2}\} \ \ \text{if } \text{arr}_i = 1 \\ \text{dp}_{i-1,2}+1 \ \ \text{if } \text{arr}_i = 0 \\ \text{dp}_{i-1,2}+2 \ \ \text{if } \text{arr}_i = -1 \end{cases} \]

posted @ 2025-12-27 15:07  Yangyihao  阅读(2)  评论(0)    收藏  举报