USACO rockers – 小溪开大船


USACO rockers – 小溪开大船
你刚刚继承了流行的"破锣摇滚"乐队录制的尚未发表的N(1 <= N <= 20)首歌的版权。你打算从中精选一些歌曲,发行M(1 <= M <= 20)张CD。每一张CD最多可以容纳T(1 <= T <= 20)分钟的音乐,一首歌不能分装在两张CD中。
不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值。于是你决定根据以下标准进行选择:
1.歌曲必须按照创作的时间顺序在所有的CD盘上出现。(注:第i张盘的最后一首的创作时间要早于第i+1张盘的第一首)
2.选中的歌曲数目尽可能地多。

格式

PROGRAM NAME: rockers
INPUT FORMAT:
(file rockers.in)
第一行: 三个整数:N, T, M.
第二行: N个整数,分别表示每首歌的长度,按创作时间顺序排列。
OUTPUT FORMAT:
(file rockers.out)
一个整数,表示可以装进M张CD盘的乐曲的最大数目。

SAMPLE INPUT

SAMPLE OUTPUT

此题是很经典的01背包问题变种,需要你对01背包解法做一些变通,这类型的题目有很多,比如有N个抽屉,需要放入M个物品等等,以后遇到这种题目就不怕不怕啦。。。。
int n, t, m;
int songs[20]; // 每首歌曲的长度
// 递归穷搜
// value为目前为止累积刻录的歌曲数量,sindex表示第i首歌,bindex表示第i张光盘,remain表示当前光盘容量
int fill(int value, int sindex, int bindex, int remain)
{
    if(sindex >= n || bindex >= m)
        return value;
    
    // 容量是否充足
    bool enough = remain >= songs[sindex];
    return std::max(fill(value, sindex + 1, bindex, remain),
               enough ?
               fill(value + 1, sindex + 1, bindex, remain - songs[sindex])
               : fill(value, sindex, bindex + 1, t));
}
 
// 非递归穷搜
int search()
{
    int max = 0;
    unsigned int mark = 1;
    unsigned int mark_max = 1 << n;
    // mark的2进制位代表第i张歌曲是否需要拷入cd
    for (; mark < mark_max; mark += 1)
    {
        int value = 0;
        int index = 0;
        int remain = t;
        
        int i = 0;
        for(; i < n; ++i)
        {
            if (mark & (1 << i))
            {
                if(songs[i] > t)
                    break;
                
                if(remain >= songs[i])
                {
                    remain -= songs[i];
                    value += 1;
                }
                else
                {
                    index += 1;
                    if(index >= m)
                        break;
                    remain = t - songs[i];
                    value += 1;
                }
            }
        }
        
        if (i == n && max < value)
            max = value;
    }
    
    return max;
}
 
int jump(int v, int j)
{
    if(v > j) return -1;
    
    return (j % t - v) >= 0 ? (j - v) : (j / t * t - v);
}
 
// 01背包的解法
// 此解法的难度在于如何在容量不足时换碟
// 技巧在于,把背包容量看成m*t大小,划分成m块,每次去判断单个块容量是否够放,如果不够则跳到下一个块
// 这样我们的背包公式可表示为
// f[i][j] = max(f[i-1][j], f[i-1][jump(songs[i], j)] + 1)
// i为第i首歌曲,j为容量,songs[i]表示为歌曲需要消耗的容量,jump函数为跳转到相应的容量位置,
// f[i][j]则表示前i个物品容量小于等于j时的最优解
// 降维打击后可变为1维,公式就不列了
int package01()
{
    
    int values[20*20 + 1] = {0};
    for(int i = 0; i < n; ++i)
    {
        for(int j = m*t; j >= songs[i]; --j)
        {
            int index = jump(songs[i], j);
            values[j] = std::max(values[j], index >= 0 ? values[index]+1 : 0);
 
            if(i == n - 1) break;
        }
    }
    
    return values[m*t];
}
 
int main()
{
    ifstream fin("rockers.in");
    ofstream fout("rockers.out");
    
    fin >> n >> t >> m;
    for(int i = 0; i < n; ++i)
    {
        fin >> songs[i];
    }
    
    // 递归穷搜超时
//    fout << fill(0, 0, 0, t);
    // 非递归穷搜通过
//    fout << search() << endl;
    // 01背包最快最经典
    fout << package01() << endl;
    
    return 0;
}
Read full article from USACO rockers – 小溪开大船

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