• uva 714 Copying Books


    Thinking about it:

      看完这题的时候,确实没有啥思路,看了题解才明白的。这个最小值是通过二分法先确定下来的,然后才能分组。这种思维方式超出了我的意料,我还一直朝着DP的思路走。看来我还需要多磨练。

    Reference:

      《算法竞赛入门经典(第2版)》

    Code:  

    /**
     * AC @ Sep 5 th 2015
     * Run Time : 0.000s
     */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 500 + 50;
    int value[MAXN];
    int M, K;
    LL sum, maxC;
    
    void read() {
        cin >> M >> K;
        sum = maxC = 0;
        for (int i = 0; i < M; ++i) {
            cin >> value[i];
            sum += value[i];
            maxC = maxC > value[i] ? maxC : value[i];
        }
    }
    
    bool is_possile(int p) {
        int tmpValue = 0, group = 1;
        for (int i = M-1; i >= 0; --i) {
            if (tmpValue + value[i] > p || i+1 <= K - group) {
                tmpValue = value[i];
                group ++;
            } else {
                tmpValue += value[i];
            }
        }
        return group == K;
    }
    
    void print(int pos, int group, int p) {
        std::vector<int> v;
        int i;
        LL sum = 0;
        for (i = pos; sum + value[i] <= p && i+1>K-group; --i) {
            sum += value[i];
            v.push_back(value[i]);
        }
        if (group == K) { // the head
            for (int l = v.size()-1; l > 0; --l) {
                cout << v[l] << " ";
            }
            cout << v[0];
        } else {
            print(i, group+1, p);
            cout << " /";
            for (int l = v.size()-1; l >= 0; --l) {
                cout << " " << v[l];
            }
        }
    }
    
    void output(int p) {
        print(M-1, 1, p);
        cout << endl;
    }
    
    void work() {
        // if left is initialized with 0, some problems will occur
        LL left = maxC, right = sum, mid;
        while (right > left) {
            mid = (right + left) >> 1;
            if (is_possile(mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        output(right);
    }
    
    int main(int argc, char const *argv[]) {
        ios::sync_with_stdio(false);        
        cin.tie(0);
        int T;
        cin >> T;
        while (T --) {
            read();
            work();
        }
        return 0;
    }
    

      

  • 相关阅读:
    Android开发总结
    Java开发中的23种设计模式详解(转)
    Linux下Tomcat的安装配置
    Linux下Tomcat的启动、关闭、杀死进程
    在陌生Linux环境查看Tomcat服务的方法
    JAVA用freemarker生成复杂Excel。(freemarker)
    JAVA生成Word文档(经过测试)
    jvm 内存溢出 在myeclipse中加大tomcat的jvm内存 java.lang.OutOfMemoryError: PermGen space
    TabHost
    ProgressBar
  • 原文地址:https://www.cnblogs.com/Emerald/p/4785205.html
Copyright © 2020-2023  润新知