Saturday, July 14, 2012

Linear Partition in C#


        static public void partition(int[] s, int n, int k) {
            Console.Write("{");
            Utils.printArray(s);
            Console.WriteLine("}");

            int MAXN = s.Length;
            int MAXK = 3;

            int[,] m = new int[MAXN, MAXK];     // DP table for values.
            int[,] d = new int[MAXN, MAXK];     // DP table for dividers.
            int[] p =  new int[MAXN];           // prefix sums array.
            int cost;

            p[0] = s[0];
            for (int i = 1; i < n; i++) p[i] = p[i - 1] + s[i];

            for (int i = 0; i < n; i++) m[i, 0] = p[i];
            for (int j = 0; j < k; j++) m[0, j] = s[0];
                       
            for (int i = 1; i < n; i++)
                for (int j = 1; j < k; j++)
                {
                    m[i, j] = int.MaxValue;
                    for (int x = 0; x <= (i - 1); x++)
                    {
                        cost = Math.Max(m[x, j - 1], p[i] - p[x]);
                        if (m[i, j] > cost)
                        {
                            m[i, j] = cost;
                            d[i, j] = x + 1;
                        }
                    }
                }

            Console.Write("{");
            reconstruct_particion(s, d, n, k);
            Console.Write("} ");
        }

        private static void reconstruct_particion(int[] s, int[,] d, int n, int k)
        {
            if (k == 1)
            {              
                print_books(s, 0, n);
            }
            else
            {
                reconstruct_particion(s, d, d[n - 1, k - 1], k - 1);
                print_books(s, d[n - 1, k - 1], n);
            }
        }

        private static void print_books(int[] s, int start, int end)
        {
            Console.Write("{");
            for (int i = start; i < end; i++)
                Console.Write(" {0} ", s[i]);
            Console.Write("} ");
        }

No comments:

Post a Comment