|  | @@ -4,46 +4,6 @@ import (
 | 
	
		
			
				|  |  |  	"fmt"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func nextPerm(nums []int) bool {
 | 
	
		
			
				|  |  | -	n := len(nums)
 | 
	
		
			
				|  |  | -	if n < 2 {
 | 
	
		
			
				|  |  | -		return false
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	i := n - 2
 | 
	
		
			
				|  |  | -	for ; 0 <= i && nums[i+1] <= nums[i]; i-- {
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if i == -1 {
 | 
	
		
			
				|  |  | -		return false
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	j := i + 1
 | 
	
		
			
				|  |  | -	for ; j+1 < n && nums[i] < nums[j+1]; j++ {
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	nums[i], nums[j] = nums[j], nums[i]
 | 
	
		
			
				|  |  | -	for l, r := i+1, n-1; l < r; l, r = l+1, r-1 {
 | 
	
		
			
				|  |  | -		nums[l], nums[r] = nums[r], nums[l]
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return true
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func countGroup(s string, perm []int) int {
 | 
	
		
			
				|  |  | -	n, k := len(s), len(perm)
 | 
	
		
			
				|  |  | -	prevByte := s[perm[0]]
 | 
	
		
			
				|  |  | -	cnt := 1
 | 
	
		
			
				|  |  | -	for offset := 0; offset < n; offset += k {
 | 
	
		
			
				|  |  | -		i := 0
 | 
	
		
			
				|  |  | -		if offset == 0 {
 | 
	
		
			
				|  |  | -			i = 1
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		for ; i < k; i++ {
 | 
	
		
			
				|  |  | -			if s[offset+perm[i]] != prevByte {
 | 
	
		
			
				|  |  | -				cnt++
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			prevByte = s[offset+perm[i]]
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return cnt
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  func main() {
 | 
	
		
			
				|  |  |  	var N, k int
 | 
	
		
			
				|  |  |  	fmt.Scan(&N)
 | 
	
	
		
			
				|  | @@ -51,17 +11,58 @@ func main() {
 | 
	
		
			
				|  |  |  		fmt.Scan(&k)
 | 
	
		
			
				|  |  |  		var S string
 | 
	
		
			
				|  |  |  		fmt.Scan(&S)
 | 
	
		
			
				|  |  | -		perm := make([]int, k)
 | 
	
		
			
				|  |  | -		for i := range perm {
 | 
	
		
			
				|  |  | -			perm[i] = i
 | 
	
		
			
				|  |  | +		n := len(S)
 | 
	
		
			
				|  |  | +		// edge[x][y] means the weight of edge: x -> y
 | 
	
		
			
				|  |  | +		// init[x][y] means the weight of edge: init point x -> y
 | 
	
		
			
				|  |  | +		edge, init := make([][]int, k), make([][]int, k)
 | 
	
		
			
				|  |  | +		for i := 0; i < k; i++ {
 | 
	
		
			
				|  |  | +			edge[i], init[i] = make([]int, k), make([]int, k)
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		minGroup := countGroup(S, perm)
 | 
	
		
			
				|  |  | -		for nextPerm(perm) {
 | 
	
		
			
				|  |  | -			groupCnt := countGroup(S, perm)
 | 
	
		
			
				|  |  | -			if groupCnt < minGroup {
 | 
	
		
			
				|  |  | -				minGroup = groupCnt
 | 
	
		
			
				|  |  | +		for x := 0; x < k; x++ {
 | 
	
		
			
				|  |  | +			for y := 0; y < k; y++ {
 | 
	
		
			
				|  |  | +				if x != y {
 | 
	
		
			
				|  |  | +					for o := 0; o < n; o += k {
 | 
	
		
			
				|  |  | +						if S[o+x] != S[o+y] {
 | 
	
		
			
				|  |  | +							edge[x][y]++
 | 
	
		
			
				|  |  | +						}
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					for o := 0; o < n-k; o += k {
 | 
	
		
			
				|  |  | +						if S[o+x] != S[o+k+y] {
 | 
	
		
			
				|  |  | +							init[x][y]++
 | 
	
		
			
				|  |  | +						}
 | 
	
		
			
				|  |  | +					} // Note: y -> x and x -> y is NOT THE SAME INIT edge!!!
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		dp := make([][]int, 1<<uint(k))
 | 
	
		
			
				|  |  | +		for i := range dp {
 | 
	
		
			
				|  |  | +			dp[i] = make([]int, k)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		const inf = 1000000
 | 
	
		
			
				|  |  | +		ans := inf
 | 
	
		
			
				|  |  | +		for beg := 0; beg < k; beg++ {
 | 
	
		
			
				|  |  | +			for i := range dp {
 | 
	
		
			
				|  |  | +				for j := range dp[i] {
 | 
	
		
			
				|  |  | +					dp[i][j] = inf
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			dp[1<<uint(beg)][beg] = 1
 | 
	
		
			
				|  |  | +			for mask := 0; mask < (1 << uint(k)); mask++ {
 | 
	
		
			
				|  |  | +				for i := 0; i < k; i++ {
 | 
	
		
			
				|  |  | +					if dp[mask][i] < inf {
 | 
	
		
			
				|  |  | +						for j := 0; j < k; j++ {
 | 
	
		
			
				|  |  | +							newset := mask | (1 << uint(j))
 | 
	
		
			
				|  |  | +							if newset != mask {
 | 
	
		
			
				|  |  | +								dp[newset][j] = minInt(dp[newset][j], dp[mask][i]+edge[i][j])
 | 
	
		
			
				|  |  | +							}
 | 
	
		
			
				|  |  | +						}
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			for i := 0; i < k; i++ {
 | 
	
		
			
				|  |  | +				ans = minInt(ans, dp[(1<<uint(k))-1][i]+init[i][beg])
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		fmt.Printf("Case #%d: %d\n", cid+1, minGroup)
 | 
	
		
			
				|  |  | +		fmt.Printf("Case #%d: %d\n", cid+1, ans)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 |