zoukankan      html  css  js  c++  java
  • 洛谷P1281 书的复制 题解 二分答案

    题目链接:https://www.luogu.com.cn/problem/P1281

    解题思路:

    二分答案。

    check(num) 用于判断每个人分配 num 也的方案是否可行,然后二分答案。
    solve(num) 函数,用于确保尽可能让前面的人少抄写。其实现给予贪心思想是:尽可能地让后面的人多抄写,则前面的人就能少抄写。

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 550;
    int m, k;
    long long a[maxn];
    bool check(long long num) {
        int id = 1;
        long long tot = 0;
        for (int i = 0; i < m; i ++) {
            if (tot+a[i] <= num) tot += a[i];
            else if (num < a[i]) return false;
            else {
                id ++;
                tot = a[i];
                if (id > k) return false;
            }
        }
        return true;
    }
    vector<pair<int, int> > res;
    void solve(int num) {
        int j = m-1;
        long long tot = 0;
        for (int i = m-1; i >= 0; i --) {
            if (tot+a[i] <= num) tot += a[i];
            else {
                res.push_back(make_pair(i+1, j));
                j = i;
                tot = a[i];
            }
        }
        res.push_back(make_pair(0, j));
        // 因为保证所有人有活可干,所以这里不额外处理了
        for (int i = k-1; i >= 0; i --) {
            cout << res[i].first+1 << " " << res[i].second+1 << endl;
        }
    }
    int main() {
        cin >> m >> k;
        long long L = 0, R = 0, res;
        for (int i = 0; i < m; i ++) {
            cin >> a[i];
            R += a[i];
        }
        while (L <= R) {
            long long mid = (L + R)/2;
            if (check(mid)) {
                res = mid;
                R = mid-1;
            }
            else L = mid+1;
        }
        solve(res);
        return 0;
    }
    
  • 相关阅读:
    android 入门-ID
    Win10 VS2015 社区版切换到VS2013社区版 进行维护之前的项目
    Win10 AppBar
    Win10 保存Element到相册
    LRUCache c#
    Winform解决界面重绘闪烁的问题
    使用Emit实现给实体赋值
    Winform 自定义窗体皮肤组件
    WPF 分享一种背景动画效果
    使用MEF与Castle实现AOP
  • 原文地址:https://www.cnblogs.com/quanjun/p/12272469.html
Copyright © 2011-2022 走看看