週末副業記

土日は副業エンジニアのブログです。副業に関することを投稿します。

競技プログラミング Atcoder Beginner Contest 167 C Skill #ビット演算 #全探索


全探索とビット演算を覚えたのでメモ。
これから全探索にビット演算を活用していきたい。

using System;
using System.Collections.Generic;
using System.Linq;

namespace easy_Atcoder
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] NMX = Array.ConvertAll(Console.ReadLine().Split(),int.Parse);
            var c = new int[NMX[0]];
            var A = new int[NMX[0],NMX[1]];
            for(int i = 0; i < NMX[0]; i++){
                var read = Array.ConvertAll(Console.ReadLine().Split(),int.Parse);
                c[i] = read[0];
                for(int j = 0; j<read.Length-1;j++){
                    A[i,j] = read[j+1];
                }
            }
            int INF = int.MaxValue;
            int ans = INF;
            
            for(var i = 1; i<(1<<NMX[0]);i++){
                var understand = new int[NMX[1]];
                var cost = 0;
                for(var j = 0; j<NMX[0];j++){
                    if(((i>>j)&1)==1){
                        for(int k = 0; k<NMX[1];k++){
                            understand[k] += A[j,k];
                        }
                        cost += c[j];
                    }
                }
                if(understand.All(x=>x>=NMX[2])){
                    ans = Math.Min(ans,cost);
                }
            }
            Console.WriteLine(ans!=INF?ans:-1);
        }
    }
}
 1<<NMX[0]

これは、1をNMX[0]分ビットシフトする。という意味。
 2^{NMX(0)}に等しい。解説の動画を見たら理解可能。
atcoder.jp
ビットが立っているところを取り出すために

((i>>j)&1)==1

を行っている。(C#では、これだけ()を付けなければならない。)
以上。