• AtCoder Regular Contest 075 2017年6月4日 C、D、E题解


    http://arc075.contest.atcoder.jp/assignments

    昨晚做的atcoder,今天写个简单题解。

    F题不会做,800point的,就跪了,要等zk大佬来做。zk能做2400的

    C题、我看到数据范围就直接100^3的背包,但是如果数据大点还是可以做的,贪心,首先全部值加起来,如果是%10==0的话,就需要去搭错一题,一题最少分的,而且%10 != 0的。

    C
    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int maxn = 1e2 + 20;
    int dp[maxn * maxn];
    void work() {
        dp[0] = true;
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            int val;
            cin >> val;
            for (int i = 10000; i >= val; --i) {
                if (dp[i - val]) dp[i] = true;
            }
        }
        int ans = 0;
        for (int i = 10000; i >= 0; --i) {
            if (dp[i]) {
                ans = max(ans, i % 10 == 0 ? 0 : i);
            }
        }
        printf("%d
    ", ans);
    }
     
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }

    D题、推公式二分,

    设x[i]表示在h[i]个位置投放的数量,sum表示x[i]的总和,那么sum就是答案,

    对于第h[i]个,需要它死亡,条件是,h[i] - (x[i] * A + (sum - x[i]) * B) <= 0

    二分答案sum,然后需要判断n个h[i]都要死亡,每个h[i]死亡,需要的x[i]继续二分,判断即可。sum是满足单调的很容易看出来,

    x[i]也满足单调因为A > B,可以化简公式看看,复杂度O(n * log * log),注意不要爆LL

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    LL n, a, b;
    LL all;
    int hi[1000000 + 20];
    LL isok(int index, LL sum) {
        LL be = 0, en = sum;
        while (be <= en) {
            LL mid = (be + en) >> 1;
            if (a * mid + (sum - mid) * b >= hi[index]) en = mid - 1;
            else be = mid + 1;
        }
        return be;
    }
    bool check(LL sum) {
        LL need = 0;
        for (int i = 1; i <= n; ++i) {
            need += isok(i, sum);
            if (need > sum) return false;
        }
        return true;
    }
    void work() {
        cin >> n >> a >> b;
        for (int i = 1; i <= n; ++i) {
            cin >> hi[i];
            all += hi[i];
        }
        if (n == 1) {
            cout << (hi[1] + a - 1) / a << endl;
            return;
        }
        LL be = 0, en = 1e9;
        while (be <= en) {
            LL mid = (be + en) >> 1;
            if (check(mid)) en = mid - 1;
            else be = mid + 1;
        }
        cout << be << endl;
    }
     
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    D

    E题、化简公式 + BIT

    设sum[i]表示前缀和,区间[L, R]满足条件,等价于sum[R] - sum[L - 1] >= (R- L + 1) * k

    等价于sum[R] - R * k >= sum[L -1] - (L - 1) * k

    相当于找前面有多少个数字比当前数字小,离散化 + bit即可。

    复杂度 nlogn

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int maxn = 2e5 + 20;
    LL sum[maxn];
    int c[maxn];
    int n, k;
    int lowbit(int x) {
        return x & (-x);
    }
    void upDate(int pos, int val) {
        while (pos <= n) {
            c[pos] += val;
            pos += lowbit(pos);
        }
    }
    int ask(int pos) {
        int ans = 0;
        while (pos) {
            ans += c[pos];
            pos -= lowbit(pos);
        }
        return ans;
    }
    LL vc[maxn], lenvc;
    void work() {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; ++i) {
            int val;
            scanf("%d", &val);
            sum[i] = sum[i - 1] + val;
        }
        for (int i = 1; i <= n; ++i) {
            sum[i] -= 1LL * i * k;
            vc[++lenvc] = sum[i];
    //        cout << sum[i] << " ";
        }
    //    cout << endl;
        sort(vc + 1, vc + 1 + lenvc);
        LL ans = 0;
        for (int i = 1; i <= n; ++i) {
            int pos = lower_bound(vc + 1, vc + 1 + lenvc, sum[i]) - vc;
            if (sum[i] >= 0) {
                ans++;
            }
            ans += ask(pos);
            upDate(pos, 1);
        }
        cout << ans << endl;
    }
     
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    E
  • 相关阅读:
    修改MyEclipse工作空间
    Servlet
    Java虚拟机类加载机制
    编译执行和解释执行
    awt和swing
    构造函数
    小知识点
    [剑指Offer]42-连续子数组的最大和/ [LeetCode]53. 最大子序和
    [剑指Offer]40-最小的k个数
    [剑指Offer]47-礼物的最大价值(DP)
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6939753.html
Copyright © 2020-2023  润新知