POJ 3273 -- Monthly Expense (最大化最小值)


POJ 3273 -- Monthly Expense (最大化最小值)
Description
Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.
FJ wants to create a budget for a sequential set of exactly M (1 ≤ M ≤ N) fiscal periods called "fajomonths". Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.
FJ's goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.
Input
Line 1: Two space-separated integers: N and M
Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day
Output
Line 1: The smallest possible monthly limit Farmer John can afford to live with.
Sample Input
7 5
100
400
300
100
500
101
400
Sample Output
500
https://amoshyc.github.io/CPsolution/poj/p3273.html


給定長度為 N 的正整數陣列 A[i],請將他分解成 M 個不重疊區間,則每個區間中有其總和 S[j],
定義 s = max(S[j] for j in range(M)) (即 S[j] 中的最大值), 請問在所有可能的分解法中,s 最小會是多少?
判斷函式為:
bool C(int d) = 分解成 M 個區間後,最大的區間和 s <= d
該函式有單調性,我們的目標是分隔點的 1 的位置(左邊數來的第一個 1 在哪):
... 0 0 0 1 1 1 1 ...
明顯地,d 越小越不容易達成。
這個函式可以用 Greedy 實作:
盡量把一個區間的值塞滿,直到塞不下。
也就是說,從左至右迭代 A[i],如果前一個區間的總和再加上 A[i] 會大於 d 的話,
則 A[i] 就是下個區間的起始點。最後看區間的數量是否 <= M

解的空間 = [max(A[i]), sum(A[i])]
下界發生在 M = N 時,每一項自己都是一個區間,此時 s = max(A[i]); 上界發生在 M = 1 時,每一項都在同一個區間裡,此時 s = sum(A[i])。
C(d) 在解的空間上存在分布全為 1 的情況,即當 C(max(A[i])) = true 情形。 可以預判掉,此時的答案就是 max(A[i])
int N, M;
int money[100000];

bool C(int s) {
    for (int i = 0; i < N; i++)
        if (money[i] > s)
            return false;

    int cnt = 0; // 區間數量
    int sum = 0; // 區間和
    for (int i = 0; i < N; i++) {
        if (sum + money[i] > s) { // 新區間
            sum = money[i];
            cnt++;
        }
        else { // 區間繼續
            sum += money[i];
        }
    }

    // 最後那個區間,前面沒有數到
    cnt++;

    return cnt <= M;
}

int solve() {
    // (lb, ub]
    int lb = *max_element(money, money + N);
    int ub = accumulate(money, money + N, 0);

    if (C(lb)) return lb;

    while (ub - lb > 1) {
        int mid = (ub + lb) / 2;
        if (C(mid)) ub = mid;
        else lb = mid;
    }

    return ub;
}

int main() {
    scanf("%d %d", &N, &M);
    for (int i = 0; i < N; i++)
        scanf("%d", &money[i]);

    printf("%d\n", solve());

    return 0;
}
http://blog.sina.com.cn/s/blog_6635898a0100ko8e.html
题意:在接下来的n天里,Farmer John每天需要花money[i]钱,把这些天分成m份(每份都是连续的天),要求每份的和尽量少,输出这个最小的和。

思路:贪心的思想,用二分去做,复杂度为O(nlogM),M = sum - max。初始状态,上界high为n天花费的总和sum,下界为每天花费的最大值max。然后二分,每次的mid值为(low+high)/ 2,然后根据mid值(估计值)遍历n天花费,看看这个mid值能把n天分成几份,如果份数大于m,表示mid偏小,low = mid + 1,反之high = mid - 1。
int main(){
    int n, m, money[Max];
    scanf("%d%d", &n, &m);
    int i, max = 0, sum = 0;
    for(i = 1; i <= n; i ++){
        scanf("%d", &money[i]);
        if(money[i] > max) max = money[i];
        sum += money[i];
    }

    int mid, low = max, high = sum;
    while(high > low){                    //  二分。
        mid = (high + low) / 2;
        int count = 1, w = 0;
        for(i = 1; i <= n; i ++){         //  count为当前mid值对应的把天分成的份数。
            w += money[i];
            if(w > mid){
                count ++;
                w = money[i];
            }
        }
        if(count > m) low = mid + 1;      //  整数在/2的时候可能造成精度不够,故可+1。
        else high = mid - 1;
    }
    printf("%d\n", high);
    return 0;
}
http://blog.csdn.net/u014688145/article/details/73610408
二分就不用说了,主要是f(m)函数,给定一个金钱范围,尽可能的塞满,问最多能塞出多少个桶。
static int N; static int M; static int[] money; public static void main(String[] args) throws IOException { Scanner in = new Scanner(System.in); N = in.nextInt(); M = in.nextInt(); money = new int[N]; int max = 0; int sum = 0; for (int i = 0; i < N; ++i){ money[i] = in.nextInt(); max = Math.max(max, money[i]); sum += money[i]; } int lf = max; int rt = sum; while (lf < rt){ int mid = lf + (rt - lf) / 2; if (valid(mid) > M) lf = mid + 1; else rt = mid; } if (valid(lf) <= M) System.out.println(lf); else System.out.println(0); } public static int valid(int m){ int cnt = 0; int sum = 0; for (int i = 0; i < N; ++i){ sum += money[i]; if (sum == m){ sum = 0; cnt++; } else if (sum > m){ sum = money[i]; cnt++; } } if (sum != 0) cnt++; return cnt; }

Read full article from 3273 -- Monthly Expense

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts