SRM 568 Div2 Medium BallsSeparating

箱がN個あり,i番目の箱にはそれぞれred[i], green[i], blue[i]のボールが入っている.
一つの箱には一つの色のボールだけしか入らないように分ける時,移動の回数を答えよという問題.
red[i], green[i], blue[i]の最小値が1なので各色につき必ず一つのボールがあるので,
N < 3の時には分けることは不可能.
逆にN ≧ 3の時には必ず分けることができる.
まずred, green, blueに振り分ける箱を3個選ぶ.
選ばれた箱の移動コストは指定された色以外のボールの総和.
それ以外の箱の移動コストは最大のボール以外を移動したほうが最小となるので,red, green, blueの合計から最大値を引いた値となる.
N ≦ 50なので約50^4回の計算になるが2秒以内に全然収まる範囲.

class BallsSeparating
{
public:
  int minOperations(vector <int> red, vector <int> green, vector <int> blue)
    {
      int n = red.size();
      if (n < 3) return -1;
      vector<int> flag(n, 0);
      flag[n-1] = 3;
      flag[n-2] = 2;
      flag[n-3] = 1;
      int i;
      int res = INT_MAX;
      do{
        int curv = 0;
        for (i = 0; i < n && curv < res; i++){
          int sum = red[i] + blue[i] + green[i];
          int tmax = 0;
          if (flag[i] == 0){
            tmax = red[i];
            int tmax2 = max(green[i], blue[i]);
            tmax = max(tmax, tmax2);
          }else if (flag[i] == 1){
            tmax = red[i];
          }else if (flag[i] == 2){
            tmax = green[i];
          }else if (flag[i] == 3){
            tmax = blue[i];
          }
          curv += sum - tmax;
        }
        res = min(res, curv);
      }while(next_permutation(flag.begin(), flag.end()));
      return res;

    }
};