分治算法

P1010 [NOIP 1998 普及组] 幂次方

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

void dfs(int n) {
    int p = (int)floor(log2(n));
    if(p == 0) cout << "2(0)";
    else if(p == 1) cout << "2";
    else {
        cout << "2(";
        dfs(p);
        cout << ")";
    }
    if(n - (1 << p) > 0) {
        cout << '+';
        dfs(n - (1 << p));
    }
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int n;
    cin >> n;
    dfs(n);

    return 0;
}

P1024 [NOIP 2001 提高组] 一元三次方程求解

思路

\(0.001\)为自区间长度分割[-100, 100],依次检验即可。时间复杂度为\(O(10^5)\)

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
const double eps = 1e-4;

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    double a, b, c, d;
    cin >> a >> b >> c >> d;
    int cnt = 0;
    for(double i = -100; i <= 100; i += 0.001) {
        if(cnt == 3) break;
        if(fabs(a * i * i * i + b * i * i + c * i + d) < eps) {
            cout << fixed << setprecision(2) << i << ' ';
            cnt++;
        }
    }
    return 0;
}

P1115 最大子段和

思路

解法一:
动态规划。\(dp[i]\)表示以\(arr[i]\)截止的所有数的最大子段和。
则递推公式为\(dp[i] = max(dp[i], dp[i - 1] + arr[i])\)时间复杂度为\(O(N)\)
解法二:

分治法,分为三部分,求取左部分最大子段和、右部分最大子段和、跨越中点的最大子段和,合并(取最大值)返回。时间复杂度为\(O(NlogN)\)

示例代码1

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> arr(n + 1);
    fer(i, 0, n) cin >> arr[i + 1];

    vector<int> dp(n + 1);

    dp[0] = 0;
    fer(i, 1, n + 1) {
        dp[i] = max(arr[i], dp[i - 1] + arr[i]);
    }
    int ans = -inf;
    fer(i, 1, n + 1) ans = max(ans, dp[i]);
    cout << ans << '\n';
    return 0;
}

示例代码2

注意part数组调用时需要加上&否则会\(TLE\)

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
const double eps = 1e-6;

int part(vector<int>& arr, int l, int r) {
    if(l == r) return arr[l];
    int mid = l + (r - l >> 1);
    int LeftMax = part(arr, l, mid);
    int RightMax = part(arr, mid + 1, r);

    int MidMax = -inf, sum = 0;
    ferd(i, mid, l) {
        sum += arr[i], MidMax = max(MidMax, sum);
    }
    sum = MidMax;
    fer(i, mid + 1, r + 1) {
        sum += arr[i], MidMax = max(MidMax, sum);
    }

    return max({LeftMax, RightMax, MidMax});
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> arr(n);
    fer(i, 0, n) cin >> arr[i];

    int res = part(arr, 0, n - 1);
    cout << res << '\n';

    return 0;
}
posted @ 2025-03-30 12:26  Thin_time  阅读(22)  评论(0)    收藏  举报