예제 #1
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(_, maxX) = inputStream.ReadValue <int, long>();
            var a = inputStream.ReadLongArray();

            var       fMax        = new long[41, 2].SetAll((_, __) => long.MinValue);
            const int EqualOrOver = 0;
            const int Under       = 1;

            fMax[40, 0] = 0;
            for (int digit = 39; digit >= 0; digit--)
            {
                long mask = 1L << digit;
                var  ones = a.Count(ai => (ai & mask) > 0);

                if ((maxX & mask) > 0)
                {
                    // Eq -> Eq (di == 1)
                    AlgorithmHelpers.UpdateWhenLarge(ref fMax[digit, EqualOrOver], fMax[digit + 1, EqualOrOver] + mask * (a.Length - ones));
                    // Eq -> Under (di == 0)
                    AlgorithmHelpers.UpdateWhenLarge(ref fMax[digit, Under], fMax[digit + 1, EqualOrOver] + mask * ones);
                }
                else
                {
                    // Eq -> Eq (di == 0)
                    AlgorithmHelpers.UpdateWhenLarge(ref fMax[digit, EqualOrOver], fMax[digit + 1, EqualOrOver] + mask * ones);
                }

                // Under -> Under
                AlgorithmHelpers.UpdateWhenLarge(ref fMax[digit, Under], fMax[digit + 1, Under] + mask * ones);
                AlgorithmHelpers.UpdateWhenLarge(ref fMax[digit, Under], fMax[digit + 1, Under] + mask * (a.Length - ones));
            }

            yield return(Math.Max(fMax[0, EqualOrOver], fMax[0, Under]));
        }
예제 #2
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(height, width, itemCount) = inputStream.ReadValue <int, int, int>();
            var       items   = new long[height, width];
            const int MaxPick = 3;

            for (int i = 0; i < itemCount; i++)
            {
                var(r, c, v) = inputStream.ReadValue <int, int, int>();
                r--;
                c--;
                items[r, c] = v;
            }

            var dp = new long[height, width, 4];

            dp[0, 0, 1] = items[0, 0];

            for (int row = 0; row < height; row++)
            {
                for (int column = 0; column < width; column++)
                {
                    if (row + 1 < height)
                    {
                        for (int currentPicked = 0; currentPicked <= MaxPick; currentPicked++)
                        {
                            for (int nextPicked = 0; nextPicked <= 1; nextPicked++)
                            {
                                AlgorithmHelpers.UpdateWhenLarge(ref dp[row + 1, column, nextPicked], dp[row, column, currentPicked] + items[row + 1, column] * nextPicked);
                            }
                        }
                    }

                    if (column + 1 < width)
                    {
                        for (int currentPicked = 0; currentPicked <= MaxPick; currentPicked++)
                        {
                            AlgorithmHelpers.UpdateWhenLarge(ref dp[row, column + 1, currentPicked], dp[row, column, currentPicked]);

                            if (currentPicked < MaxPick)
                            {
                                AlgorithmHelpers.UpdateWhenLarge(ref dp[row, column + 1, currentPicked + 1], dp[row, column, currentPicked] + items[row, column + 1]);
                            }
                        }
                    }
                }
            }

            long max = 0;

            for (int picked = 0; picked <= MaxPick; picked++)
            {
                AlgorithmHelpers.UpdateWhenLarge(ref max, dp[height - 1, width - 1, picked]);
            }

            yield return(max);
        }
예제 #3
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(n, capacity) = inputStream.ReadValue <int, int>();
            var items = new Item[n];

            for (int i = 0; i < items.Length; i++)
            {
                var(w, v) = inputStream.ReadValue <int, int>();
                items[i]  = new Item(w, v);
            }
            var baseW = items[0].Weight;

            for (int i = 0; i < items.Length; i++)
            {
                items[i] = new Item(items[i].Weight - baseW, items[i].Value);
            }

            const int maxCapacity = 300;
            var       maxValues   = new int[n + 1, n + 1, maxCapacity];

            for (int i = 0; i < n; i++)
            {
                for (int selected = 0; selected <= i; selected++)
                {
                    for (int w = 0; w < maxCapacity; w++)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref maxValues[i + 1, selected, w], maxValues[i, selected, w]);

                        if (w + items[i].Weight < maxCapacity)
                        {
                            AlgorithmHelpers.UpdateWhenLarge(ref maxValues[i + 1, selected + 1, w + items[i].Weight], maxValues[i, selected, w] + items[i].Value);
                        }
                    }
                }
            }

            var max = int.MinValue;

            for (int selected = 0; selected <= n; selected++)
            {
                for (int w = 0; w < maxCapacity; w++)
                {
                    if ((long)baseW * selected + w <= capacity)
                    {
                        max = Math.Max(max, maxValues[n, selected, w]);
                    }
                }
            }

            yield return(max);
        }
예제 #4
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var maxWidth = inputStream.ReadInt();

            var(screenShotCount, maxScreenShotCount) = inputStream.ReadValue <int, int>();

            var screenShots = new ScreenShot[screenShotCount];

            for (int i = 0; i < screenShotCount; i++)
            {
                var(a, b)      = inputStream.ReadValue <int, int>();
                screenShots[i] = new ScreenShot(a, b);
            }

            var importantness = new int[screenShotCount + 1, maxScreenShotCount + 1, maxWidth + 1];

            for (int ss = 0; ss < screenShotCount; ss++)
            {
                for (int taken = 0; taken <= maxScreenShotCount; taken++)
                {
                    for (int w = 0; w <= maxWidth; w++)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref importantness[ss + 1, taken, w], importantness[ss, taken, w]);

                        var nextWidth = w + screenShots[ss].Width;
                        if (nextWidth <= maxWidth && taken < maxScreenShotCount)
                        {
                            AlgorithmHelpers.UpdateWhenLarge(ref importantness[ss + 1, taken + 1, nextWidth], importantness[ss, taken, w] + screenShots[ss].Importantness);
                        }
                    }
                }
            }

            var maxImportantness = 0;

            for (int ss = 0; ss <= maxScreenShotCount; ss++)
            {
                for (int w = 0; w <= maxWidth; w++)
                {
                    AlgorithmHelpers.UpdateWhenLarge(ref maxImportantness, importantness[screenShotCount, ss, w]);
                }
            }

            yield return(maxImportantness);
        }
예제 #5
0
        void Initialize(int halfN)
        {
            _values = new int[halfN, maxCapacity + 1];

            for (int i = 1; i < halfN; i++)
            {
                for (int w = 0; w <= maxCapacity; w++)
                {
                    AlgorithmHelpers.UpdateWhenLarge(ref _values[i, w], _values[i >> 1, w]);

                    var nextWeight = w + _goods[i].Weight;
                    if (nextWeight <= maxCapacity)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref _values[i, nextWeight], _values[i >> 1, w] + _goods[i].Value);
                    }
                }
            }
        }
예제 #6
0
 int GetValueAt(int index, int capacity)
 {
     if (index < _values.GetLength(0))
     {
         return(_values[index, capacity]);
     }
     else
     {
         var nextIndex = index >> 1;
         var value     = 0;
         AlgorithmHelpers.UpdateWhenLarge(ref value, GetValueAt(nextIndex, capacity));
         var nextCapacity = capacity - _goods[index].Weight;
         if (nextCapacity >= 0)
         {
             AlgorithmHelpers.UpdateWhenLarge(ref value, GetValueAt(nextIndex, nextCapacity) + _goods[index].Value);
         }
         return(value);
     }
 }
예제 #7
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(jankenCount, restriction) = inputStream.ReadValue <int, int>();
            var winPoints = inputStream.ReadIntArray();
            var pattern   = inputStream.ReadLine().Select(c => ToHand(c)).ToArray();

            var totalPoints = 0;

            for (int mod = 0; mod < restriction; mod++)
            {
                var subJankens = (jankenCount - mod + restriction - 1) / restriction;
                var points     = new int[subJankens + 1, 3];

                for (int round = 0; round < subJankens; round++)
                {
                    var index = round * restriction + mod;
                    for (int before = Rock; before <= Paper; before++)
                    {
                        for (int current = Rock; current <= Paper; current++)
                        {
                            if (before != current)
                            {
                                AlgorithmHelpers.UpdateWhenLarge(ref points[round + 1, current],
                                                                 points[round, before] + (Wins(current, pattern[index]) ? winPoints[current] : 0));
                            }
                        }
                    }
                }

                var total = 0;

                for (int hand = Rock; hand <= Paper; hand++)
                {
                    total = Math.Max(total, points[subJankens, hand]);
                }

                totalPoints += total;
            }

            yield return(totalPoints);
        }
예제 #8
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var n       = inputStream.ReadInt();
            var infants = inputStream.ReadIntArray().Select((a, index) => new Infant(a, index)).ToArray();

            Array.Sort(infants);
            Array.Reverse(infants);

            var happiness = new long[n + 1, n + 1];     // [left人数, right人数]

            for (int i = 1; i <= n; i++)
            {
                var infant = infants[i - 1];

                for (int leftCount = 0; leftCount <= i; leftCount++)    // left 0人~i人
                {
                    var rightCount = i - leftCount;

                    // 左に配置
                    if (leftCount > 0)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref happiness[leftCount, rightCount], happiness[leftCount - 1, rightCount] + infant.GetHappiness(leftCount - 1));  // leftCount=1のとき座標は0
                    }
                    // 右に配置
                    if (rightCount > 0)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref happiness[leftCount, rightCount], happiness[leftCount, rightCount - 1] + infant.GetHappiness(infants.Length - rightCount));    // rightCount=1のとき座標はn-1
                    }
                }
            }

            long max = 0;

            for (int leftCount = 0; leftCount <= n; leftCount++)
            {
                var rightCount = n - leftCount;
                AlgorithmHelpers.UpdateWhenLarge(ref max, happiness[leftCount, rightCount]);
            }

            yield return(max);
        }
예제 #9
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(dishKinds, lastOrder) = inputStream.ReadValue <int, int>();
            var dishes = new Dish[dishKinds];

            for (int i = 0; i < dishKinds; i++)
            {
                var(a, b) = inputStream.ReadValue <int, int>();
                dishes[i] = new Dish(a, b);
            }

            Array.Sort(dishes);
            var maxMinutes = lastOrder + 3000;

            var happinesses = new int[dishKinds + 1, maxMinutes + 1];

            for (int i = 0; i < dishes.Length; i++)
            {
                for (int minutes = 0; minutes <= maxMinutes; minutes++)
                {
                    AlgorithmHelpers.UpdateWhenLarge(ref happinesses[i + 1, minutes], happinesses[i, minutes]);

                    if (minutes < lastOrder)
                    {
                        AlgorithmHelpers.UpdateWhenLarge(ref happinesses[i + 1, minutes + dishes[i].NeedToEat], happinesses[i, minutes] + dishes[i].Deliciousness);
                    }
                }
            }

            var max = 0;

            for (int minutes = 0; minutes <= maxMinutes; minutes++)
            {
                AlgorithmHelpers.UpdateWhenLarge(ref max, happinesses[dishKinds, minutes]);
            }
            yield return(max);
        }
예제 #10
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var n       = inputStream.ReadInt();
            var infants = inputStream.ReadIntArray().Select((a, index) => new Infant(a, index)).ToArray();

            Array.Sort(infants);
            Array.Reverse(infants);

            var dpStatus = new DPStatus[n + 1, 2];     // left of right

            dpStatus[0, 0] = new DPStatus(0, 0, infants.Length - 1);
            dpStatus[0, 1] = new DPStatus(0, 0, infants.Length - 1);


            for (int i = 0; i < n; i++)
            {
                var infant = infants[i];

                var beforeLeft  = dpStatus[i, 0];
                var beforeRight = dpStatus[i, 1];

                // 左に並べるとき
                AlgorithmHelpers.UpdateWhenLarge(ref dpStatus[i + 1, 0],
                                                 new DPStatus(beforeLeft.Happiness + infant.Briskness * Math.Abs(infant.Position - beforeLeft.LeftIndex), beforeLeft.LeftIndex + 1, beforeLeft.RightIndex));
                AlgorithmHelpers.UpdateWhenLarge(ref dpStatus[i + 1, 0],
                                                 new DPStatus(beforeRight.Happiness + infant.Briskness * Math.Abs(infant.Position - beforeRight.LeftIndex), beforeRight.LeftIndex + 1, beforeRight.RightIndex));


                // 右に並べるとき
                AlgorithmHelpers.UpdateWhenLarge(ref dpStatus[i + 1, 1],
                                                 new DPStatus(beforeLeft.Happiness + infant.Briskness * Math.Abs(infant.Position - beforeLeft.RightIndex), beforeLeft.LeftIndex, beforeLeft.RightIndex - 1));
                AlgorithmHelpers.UpdateWhenLarge(ref dpStatus[i + 1, 1],
                                                 new DPStatus(beforeRight.Happiness + infant.Briskness * Math.Abs(infant.Position - beforeRight.RightIndex), beforeRight.LeftIndex, beforeRight.RightIndex - 1));
            }

            yield return(Math.Max(dpStatus[n, 0].Happiness, dpStatus[n, 1].Happiness));
        }
 public void UpdateWhenLargeTest(int first, int second, int expected)
 {
     AlgorithmHelpers.UpdateWhenLarge(ref first, second);
     Assert.Equal(expected, first);
 }