wikioi 1048 石子归并


http://www.voidcn.com/article/p-ybexlmby-wd.html
有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。
第一行一个整数n(n<=100)
第二行n个整数w1,w2...wn  (wi <= 100)
一个整数表示最小合并代价
4
4 1 1 4
18
https://blog.csdn.net/fuyukai/article/details/43793863
区间型动态规划是我个人感觉动态规划类型里面最好理解的一种

拿到题目的时候,我首先想到的是“合并果子”那道题,做法大概是建堆+贪心,可是仔细看一下,两道题目却有很大不同,这道题合并的时候需要两石子相邻,明显贪心已经做不了了,所以我们用动规来试试看。区间型的动规,就是与区间有关的DP,我们需要考虑区间的一些特点来解决:
不妨用dp[i][j]表示合并 i 到 j 这一区间的石子所产生的消耗,那我们最终的结果就是dp[1][n],我们怎么才能得到最重的dp[1][n]呢?
状态转移方程是:dp[i][j]=min(dp[i][j] , dp[i][k] + dp[k+1][j] + sum[i:j])
我们需要从两个石子开始合并,最终变成 n 个石子开始合并,代码如下:

for(int len=2;len<=n;len++)
{
    for (int i=1;i<=n-len+1;i++)
    {
        int j=i+len-1;
        for (int k=i;k<j;k++)
            dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
    }
}
1
2
3
4
5
6
7
8
9
我们事先需要预处理一下,获得sum数组(省去了一个二重循环):

for (int i=1;i<=n;i++)
    sum[i]=sum[i-1]+a[i];

https://www.cnblogs.com/qscqesze/p/4010949.html
dp[i][j]=min(dp[i][j],dp[i][k],dp[k+1][j]+sum[i][j]);
表示i-j的最小合并代价。
13     int getMinval(int a[],int n)  
14     {  
15         for(int i=0;i<n;i++)  
16             dp[i][i] = 0;  
17         for(int v=1;v<n;v++)  
18         {  
19             for(int i=0;i<n-v;i++)  
20             {  
21                 int j = i + v;  
22                 dp[i][j] = INF;  
23                 int tmp = sum[j] - (i > 0 ? sum[i-1]:0);  
24                 for(int k=i;k<j;k++)  
25                     dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j] + tmp);  
26             }  
27         }  
28         return dp[0][n-1];  
29     }  
30       
31     int main()  
32     {  
33         int n;  
34         while(scanf("%d",&n)!=EOF)  
35         {  
36             for(int i=0;i<n;i++)  
37                 scanf("%d",&a[i]);  
38             sum[0] = a[0];  
39             for(int i=1;i<n;i++)  
40                 sum[i] = sum[i-1] + a[i];  
41             printf("%d\n",getMinval(a,n));  
42         }  
43         return 0;  
44     }  
http://www.voidcn.com/article/p-ybexlmby-wd.html
题意:给出n个数,相邻两数可以合并,合并的代价是两数之和,问合并成一个数的最小代价。
分析:典型的区间dp,用dp[i][j]记录[i,j]区间合并为一个数的最小代价,那么递推方程:dp[i][j] = min(dp[i][k]+dp[k][j])+sum[i][j],其中i<k<j,sum[i][j]为[i,j]区间的和,也就是本次合并的代价。先从i-j=1开始遍历,逐步增大[i,j]区间的长度,最终dp[0][n-1]即为结果
ps:注意边界,如dp[i][i] = 0, sum[i][i] = a[i],a[i]就是第i个数的值
    int n;
    cin>>n;
    memset(sum,0,sizeof(sum));
    for(int i=0; i<n; i++)
    {
        cin>>sum[i][i];
        for(int j=0; j<i; j++)
            sum[j][i] = sum[j][i-1]+sum[i][i];
    }
    memset(dp,0,sizeof(dp));
    for(int k=1;k<n;k++)
    {
        for(int i=0; i+k<n; i++)
        {
            int minn = -1;
            for(int j=i;j<i+k;j++)
            {
                if(minn<0 || dp[i][j]+dp[j+1][i+k] < minn)
                    minn = dp[i][j]+dp[j+1][i+k];
            }
            dp[i][i+k] = minn + sum[i][i+k];
        }
    }
    cout<<dp[0][n-1]<<endl;
sum[i[用于记录从第1堆到第i堆(包含i)石子的总重量。

dp[i][j]表示从第i堆(包含i)到第j堆(包含j)石子的合并的最小代价。

状态转移方程为:dp[i][j] = minimize{dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]}, k从i到j(不包含j)。

len=2表示第一次合并的情况,此时合并的石子为2堆。此时,i从1到n-len+1,j=i+len-1。


Different
https://dannyyo.iteye.com/blog/2172612
GarsiaWachs算法

11079 可以移动的石子合并(必做)

有n堆石子形成一行(a1,a2,…,an,ai为第i堆石子个数),现要将石子合并成一堆,规定每次可选择至少2堆最多k堆移出然后合并,每次合并的分值为新堆的石子数。
若干次合并后,石子最后肯定被合并为一堆,得分为每次合并的分值之和。
现在求解将这n堆石子合并成一堆的最低得分和最高得分。


输入格式

两行。第一行n和k,第二行a1 a2 … an,每个ai(1<=i<=n)表示第i堆石子的个数,n<=100,2<=k<=n。

输出格式

仅一行,为石子合并的最低得分和最高得分,中间空格相连。

输入样例

7 3
45 13 12 16 9 5 22

输出样例

199 593



提示

此题贪心算法求解.
给这题标记标签"dp"方法是同学所为,并非老师标注.动规不是不可以,但有更好更快的贪心解法的.

如7堆石头,每次可选择最少2堆最多3堆合并,可以如下这样合并:
第1次合并:45+22=67
第2次合并:67+16=83
第3次合并:83+13=96
第4次合并:96+12=108
第5次合并:108+9=117
第6次合并:117+5=122
合并的总分值:67+83+96+108+117+122=593,593已是最大分值。

也可以这样合并:
第1次合并:5+9+12=26
第2次合并:13+16+22=51
第3次合并:45+51+26=122
合并的总分值:26+51+122=199,199已是最小分值。

因此此题贪心的方法如下:

(1)保证每次选两堆最多的,合并直至只剩一堆为止,能获得最大得分;
这个和huffman树构造是相同的,不再详述!

(2)保证每次选k堆最少的,合并直至只剩一堆为止,能获得最小得分。
这个是多元huffman树的构造。要注意的是:在合并之前,若n%(k-1)!=1,说明合并到最后一轮时,剩下不是k堆(而是比k堆少),这样算的并不是最小得分,
而必须在合并之前添加若干个为0的虚拟堆,目的为凑成的堆数保证每次都能有k堆合并(包括最后一次)最后合并为1堆。
因此,在合并前作如下处理:

//假设石头每堆个数放于stone[1]~stone[n],且stone[n]之后最多k-1个数组单元为可写;
while (n % (k - 1) != 1)
{
        n++;
        stone[n]=0;
}



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