AtCoder Beginner Contest 167 C Problem (Java)

Introduction

AtCoder Beginner Contest 167 of C problem (C-Skill Up) of I haven't seen the explanation video. Or, it is an article for those who have seen but are worried whether they understood it.

I saw the commentary on the video, but I've put it together for organization.

The explanation video is also very easy to understand, so Please refer to that as well. C problem is around 21:30 to 42:00. The explanation video is here.

** How to try all combinations of numbers from 1 to N **.

problem

The problem statement can be summarized as follows.

There are M algorithms that Takahashi wants to learn, There are N algorithm reference books in the bookstore.

Takahashi has a budget to buy all the reference books, If possible, I want to learn efficiently and keep the minimum expense.

In what order should you buy and read the reference books to save the most money? Find the minimum cost.

How to solve

** Buy N reference books Try all combinations **

There are "1 << N" combinations for purchasing N reference books.

<< is a shift operation. "1 << N" means to shift 1 to the left by N pieces.

The shift operation is considered in binary.


Binary number

0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000

Example: 1 << 3 It means to shift 0001 to the left by three, so It will be 0001000. Therefore, it is "8" in decimal.

Therefore, if N of N books is "3", the combination will be "8 patterns".

Why is that so?

Look at the binary numbers 0-7 above. If you pay attention to the 3 digits from the right, you can see that all patterns are covered by 0 to 7.

Think of each of these digits as whether to buy each reference book.

Example: When there are 3 reference books

000-> Case where you do not buy even one book
001-> The case where you buy the first reference book but not the second and third
010-> The case where you buy the second reference book but not the first and third
011-> Buy the first and second reference books, but not the third
100-> The case where you buy the third reference book but not the first and second
101-> A case where you buy the first and third reference books, but not the second
110-> Buy the second and third reference books, but not the first
111-> Case to buy all

Source code that loops 8 patterns when n = 3


class Main {
  public static void main(String[] args) {
    int patternCount = 1 << 3;
    System.out.printf("patternCount=%d\n", patternCount);

    for (int i = 0; i < patternCount; i++) {
      System.out.println(Integer.toBinaryString(i));
    }
  }
}

↑ It loops 8 patterns, so you can simply loop 8 times. I tried to output 0 to 7 in binary.

Output result


patternCount=8
0
1
10
11
100
101
110
111

Look at the books you buy and the books you don't buy in each pattern

Let's look at books to buy and books not to buy depending on whether each digit in binary is 1.

If it is 001, the first reference book is bought, but the second and third are not. If it is 110, buy the second and third reference books, but not the first

It's like that.

In other words

When buying the first book, the first number counting from the right is 1. When buying the second book, the second number counting from the right is 1. When buying the third book, the third number from the right is 1.

That's right.

Use the "&" operator to find out if the digit specified in binary is 1.

The "&" operator is set to 1 only if both digits of each digit are 1 in the binary representation.

Let's express it in binary for easy understanding.

1111 & 0001 -> 0001 1111 & 1001 -> 1001 1000 & 1001 -> 1000

In this way, it is an operation that compares each digit of the left and right binary numbers and sets that digit to 1 only when both are 1.

Take advantage of this

--To find out if you bought the first book, check if the result of & with 001 is 001 --To find out if you bought a second book, check if the result of & on 010 is 010 --To find out if you bought a third book, check if the result of & with 100 is 100

It will be.

class Main {
  public static void main(String[] args) {
    int n = 3;
    System.out.printf("n=%d\n", n);
    int patternCount = 1 << n;
    System.out.printf("patternCount=%d\n", patternCount);

    for (int i = 0; i < patternCount; i++) {
      System.out.println(Integer.toBinaryString(i));
      for (int j = 0; j < n; j++) {
        if ( (i & 1<<j) == 1<<j) {
          System.out.printf("   %Buy the dth reference book\n", j + 1);
        }
      }
    }
  }
}

↑ In this way, check whether each digit of the binary number is 1. The output result is as follows.

n=3
patternCount=8
0
1
Buy the first reference book
10
Buy a second reference book
11
Buy the first reference book
Buy a second reference book
100
Buy a third reference book
101
Buy the first reference book
Buy a third reference book
110
Buy a second reference book
Buy a third reference book
111
Buy the first reference book
Buy a second reference book
Buy a third reference book

Find the minimum purchase cost

Now we have the foundation to solve this problem. Try all the patterns to see the lowest purchase cost.

In the source code below, C problem is AC.

import java.util.*;
class Main {
  final static int INF = 1001001001;

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    //Store input data in a variable
    int n = sc.nextInt();
    int m = sc.nextInt();
    int x = sc.nextInt();
    int[][] a = new int[12][12];
    int[] c = new int[n];
    for (int i = 0; i < n; i++) {
      c[i] = sc.nextInt();
      for (int j = 0; j < m; j++) {
        a[i][j] = sc.nextInt();
      }
    }
    sc.close();

    //Answer=Since it is the minimum cost value, initialize it with a large number for comparison of the minimum value.
    int ans = INF;

    //Check all combination patterns
    for (int s = 0; s < 1<<n; s++) {
      int cost = 0;         //The cost of this s th combination
      int[] d = new int[m]; //Understanding of each algorithm in this sth combination

      //Check if each bit is 1 in binary
      for (int i = 0; i < n; i++) {

        //If the i-th bit from the right is 1, add the cost and algorithm as a reference book to purchase.
        if ( (s & 1<<i) == 1<<i) {
          //Add cost
          cost += c[i];

          //Add to the understanding of each algorithm
          for (int j = 0; j < m; j++) {
            d[j] += a[i][j];
          }
        }
      }

      //Check if the comprehension of all algorithms exceeds x
      boolean ok = true;
      for (int j = 0; j < m; j++) {
        if (d[j] < x) ok = false; //If even one is less than x.
      }
      //If the check is OK, whether the cost updates the minimum value.
      if (ok) ans = Math.min(ans, cost);

    }

    //Ans remains INF if there is no pattern in which the comprehension of all algorithms exceeds x
    if (ans == INF) System.out.println(-1);
    else System.out.println(ans);

  }
}

in conclusion

What did you think?

** Try all combinations of numbers from 1 to N **

I think that this solution can be used when encountering such a problem.

end.

Recommended Posts

AtCoder Beginner Contest 167 C Problem (Java)
AtCoder Beginner Contest 132 D Problem
Solve AtCoder Beginner Contest 151 in java
Solve AtCoder Beginner Contest 150 in java
Solve AtCoder Beginner Contest 175 in java
Solve AtCoder Beginner Contest 160 in java
AtCoder Beginner Contest 168
Solve AtCoder Beginner Contest 152 in java
Solve AtCoder Beginner Contest 156 in java
atcoder ABC113 C problem
atcoder ABC115 C problem
AtCoder Beginner Contest 169 A, B, C with ruby
AtCoder Beginner Contest 182 Participation Article
AtCoder Beginner Contest 170 A, B, C up to ruby
java beginner 4
java beginner 3
java beginner
Solving with Ruby AtCoder ACL Beginner Contest C Union Find (DSU)
[Java] Problem No. 2
[Java] Problem No.3
Java Beginner Exercises
[Java] Problem No.1
Java Exercise "Beginner"
Solving with Ruby, Perl and Java AtCoder ABC 128 C
atcoder ABC70 D problem
Solving in Ruby, Perl and Java AtCoder ABC 113 C Reference
AtCoder dwango Programming Contest B in Ruby, Perl and Java
Solving with Ruby, Perl and Java AtCoder ABC 129 C (Part 1)
Progate Java (Beginner) Review & Summary
Java starting from beginner, override
Zunda's 1-digit addition problem Java 11
Fastest Primality Test C # Java C ++
Java, instance starting from beginner
AtCoder Challenge Environment Construction (Java 8)
Java starting from beginner, inheritance
Reproduce Java enum in C #
C # and Java Overrides Story
[Beginner] Java basic "array" description