lixolas's blog

By lixolas, history, 6 years ago, In English

Yup, you read it right ;)

I know this isn't really a big thing, but still is something that might help when you are about to code a DP which has to optimized in memory.

So, take, for instance the Knapsack problem:

Background

You have N items, each with profit Pi and weight Wi. You want to fit the items in a Knapsack with max capacity of B. What is the max profit you can have?

The usual solution for this DP uses 2 dimensions: dp[i][j] stores the max profit using until the i-th item, with total weight j. So we have the following recursion:

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - Wi] + Pi).

"Ok, but what is this all for anyway?"

So, first notice that we are dealing with 2 dimensions; the first one is just an index for the items, and the second one is the capacity we are dealing with right now. Also, notice that we are only going backwards in the second dimension. Because of this structure, we could replace the classic 2-dimension code by the following:

for(int i=0; i<N; i++) {
    for(int j=B; j>=0; j--) {
        if(j - W[i] >= 0) {
            dp[j] = max(dp[j], dp[j-W[i]] + P[i]);
        }
    }
}

To retrieve the answer, just take max(dp[j]) between all valid j.

This trick only works because we are walking backwards in the weight dimension instead of forwards. So, when we are updating the DP, we won't mess up and risk using the same item twice (which could easily happen if we went forwards with j). This strategy is sometimes useful when you want to use a DP which goes well in time, but not so much in memory =P

This could be used in the recent contest problem 1078B - The Unbearable Lightness of Weights, and this was, actually, my motivation for writing this blog. My AC submission uses this logic: 45977998.

A little down: you can't recover the list of the items by this method, only the rock-solid answer.

That's it, folks! Have a good day/noon/night! ;)

Full text and comments »

  • Vote: I like it
  • +13
  • Vote: I do not like it

By lixolas, history, 7 years ago, In English

Hello everyone,

on last CodeForces, the problem A of Div1 Contest (this problem) was about some GCD operations. My solution (by the way, totally overkill, despite the fact that some people may have used the same idea) used binary search and some prefix sum matrix (for checking if GCD on range equals 1), only considering primes smaller than 40,050. Although it is getting AC (my solution during the contest, translated to english), I figured out a case where it fails:

2

524287 524287

(actually, it could be any prime numbers greater than 40,050.)

In this case the solution is -1 (because the gcd of two equal numbers is the number itself), however, my code prints 1 as the answer. Is there anything that can be done about this?

Full text and comments »

  • Vote: I like it
  • +19
  • Vote: I do not like it

By lixolas, history, 7 years ago, In English

Hello everyone!

I was competing at CS Academy earlier today. After some time, I started to think about problem E (link is here: http://csacademy.com/contest/round-53/task/maxor/). The problem is basically to find the maximum bitwise OR operation of 2 elements in the array, and how many pair of elements have this value. I figured out a different solution of the editorial: we can make an FFT multiplication of the array, but instead of multiplication we use the OR operation. This could give the answer. But I searched for it on the internet and found nothing about this FFT. I thought it was worth asking here: have anyone of you heard about FFT of bitwise OR?

Full text and comments »

  • Vote: I like it
  • +29
  • Vote: I do not like it