Problem:
ぬいぐるみの整理 (Plush Toys)

問題

ある JOI 関係者は，おもちゃ屋で働いている．今日は，店内にあるぬいぐるみコーナーの整理をすることになった．

ぬいぐるみコーナーの棚には，N 個のぬいぐるみが左から右に一列に並べられている．棚は仕切りにより N 個の区画に区切られており，1 つの区画に 1 個のぬいぐるみを置く．このおもちゃ屋は合計 M 種類のぬいぐるみを売っており，それぞれ 1 から M までの番号が付けられている．棚に並べられた N 個のぬいぐるみは，それぞれこの M 種類のうちのいずれかである．また，それぞれの種類のぬいぐるみは，少なくとも 1 個は存在する．

見栄えを良くするため，同じ種類のぬいぐるみが全て連続して棚に置かれるように，ぬいぐるみを並べ替えたい．次のような方法で，ぬいぐるみを並べ替えることにした．

N 個のぬいぐるみのうちいくつかを選び，棚から取り出す．取り出さなかったぬいぐるみの位置は動かさない．

取り出したぬいぐるみを，好きな順に棚の空いている区画に戻していく．

並べ替えた後，同じ種類のぬいぐるみが全て連続して棚に置かれていなければならない．
並べ替えるために取り出すぬいぐるみの個数の最小値を求めるプログラムを作成せよ．

入力

入力は 1 + N 行からなる．

1 行目には 2 個の整数 N, M (1 ≦ N ≦ 100000, 1 ≦ M ≦ 20) が空白を区切りとして書かれており，ぬいぐるみが N 個あり，種類が M 種類あることを表す．

続く N 行のそれぞれには，1 以上 M 以下の整数が書かれている． N 行のうちの i 行目 (1 ≦ i ≦ N) に書かれた整数は，棚の左から i 番目の区画に置かれたぬいぐるみの種類を表す．各種類について，少なくとも 1 個のぬいぐるみが存在していることが保証される．

出力

並べ替えるために取り出すぬいぐるみの個数の最小値を 1 行で出力せよ．

入出力例

入力例 1

7 2
1
2
2
2
1
2
1

出力例 1

2

入力例 2

12 4
1
3
2
4
2
1
2
3
1
1
3
4

出力例 2

7

入力例 1 においては，最初に置かれているぬいぐるみの種類は左から順に 1， 2， 2， 2， 1， 2， 1 である．並べ替えるために取り出すぬいぐるみの個数を最小にするには，左から 1 番目と 6 番目のぬいぐるみを取り出し，左から 1 番目に種類 2 のぬいぐるみを，左から 6 番目に種類 1 のぬいぐるみを配置すればよい．このとき，取り出すぬいぐるみの個数は 2 個である．

情報オリンピック日本委員会作 『第 16 回日本情報オリンピック JOI 2016/2017 予選競技課題』

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.Scanner;

//listを配列に変更したバージョン

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		Scanner sc = new Scanner(System.in);
		int spaceNum = sc.nextInt();
		int dollTypeNum = sc.nextInt();
		int space[] = new int[spaceNum];  //棚の初期状態
		int dollType[] = new int[dollTypeNum];  //ぬいぐるみが種類ごとにいくつあるか(添え字に注意)
		int cursor = 0;
		int count = 0;

		int flag[] = new int[dollTypeNum];  //ぬいぐるみの種類ごとに使用したかどうかを判定するフラグ

		for(int i = 0; i < spaceNum; i++) {
			space[i] = sc.nextInt();
			for(int j = 1; j <= dollTypeNum; j++) {
				if(space[i] == j) {
					dollType[j - 1]++;
					break;
				}
			}
		}
		////////////////////////////////////////////////////////////////////ここまではOK

		for(int i = 0; i < dollTypeNum; i++) {
			FillIn2 fi = new FillIn2();
			fi.fill_in(cursor, space, flag, dollType);
			cursor += dollType[fi.getNum() - 1];
			count += fi.getMin();

			flag[fi.getNum() - 1] = 1;
		}

		System.out.println(count);
	}
}

class FillIn2 {
	private int num = 0;
	private int min = Integer.MAX_VALUE;
	//最小の操作回数で埋められるぬいぐるみ番号を探すメソッド
	/*  fill_in_in_order(埋める開始点, 操作前のぬいぐるみ配列, 埋め終わってないぬいぐるみ番号を入れたリスト,
	ぬいぐるみ番号別の個数を入れた配列);  */
	public void fill_in(int start, int[] array, int[] flag, int[] type) {
		int cursor;
		int count = 0;
		for(int i = 0; i < flag.length; i++) {  //埋め終わってないぬいぐるみ番号のループ
			cursor = start;
			count = 0;
			if(flag[i] == 0) {
				for(int j = 0; j < type[i]; j++) {  //その番号のぬいぐるみの個数のループ
					if(array[cursor] == i + 1) count++;
					cursor++;
				}
				if(type[i] - count < min) {
					//iのforループを回してここで求めたnumが最小操作回数で埋められるぬいぐるみ番号、minがその操作回数
					num = i + 1;
					min = type[i] - count;
				}
			}
		}
	}

	public int getNum() {
		return this.num;
	}

	public int getMin() {
		return this.min;
	}

}