package main import . "fmt" import . "os" import bf "bufio" import . "sort" type T struct { v,index,side int } func main() { rd:=bf.NewReader(Stdin) var n,m int Fscan(rd,&n,&m) ls := make([]int, m) rs := make([]int, m) for i := range ls { Fscan(rd,&ls[i], &rs[i]) } ans := solve(n, m, ls, rs) Println(ans) } func solve(n,m int, ls, rs []int) int { ts := make([]*T, 0, m*2) for i := 0; i < m; i++ { L := &T{ ls[i], i, 0 } R := &T{ rs[i], i, 1 } ts = append(ts, L, R) } Slice(ts, func(i, j int) bool { d := ts[i].v - ts[j].v if d == 0 { return ts[i].side < ts[j].side } else { return d < 0 } }) removed := make([]bool, m) current := []*T{} zeros := 0 for len(ts) > 0 { t := ts[0] ts = ts[1:] if t.side == 0 { current = append(current, t) } else if !removed[t.index] { zeros++ for _, c := range current { removed[c.index] = true } current = current[:0] } } return n-zeros } func init() { check() } func check() { const n = 10 const m = 5 ls := make([]int, m) rs := make([]int, m) used := make([]bool, n+1) cnt := 0 var tes func(i int) tes = func(i int) { if i == m { cnt++ ans := solve(n, m, ls, rs) expect := bruteforce(n, m, ls, rs) if ans != expect { println("n=",n) println("m=",m) println(Sprintf("ls=%#v", ls)) println(Sprintf("rs=%#v", rs)) println("ans=",ans) println("expect=",expect) panic("bug") } return } for x := 1; x <= n; x++ { if used[x] { continue } for y := x; y <= n; y++ { if used[y] { continue } ls[i] = x rs[i] = y used[x] = true used[y] = true tes(i+1) used[x] = false used[y] = false } break } } tes(0) println("cnt=",cnt) } func bruteforce(n,m int, ls,rs []int) int { ans := 0 for i := 0; i < (1 << n); i++ { zerosum := make([]int, n+1) for k,v := 0,i; k < n; k++ { if (v&1) != 0 { zerosum[k+1] = 1 } v >>= 1 } for k := 0; k < n; k++ { zerosum[k+1] += zerosum[k] } ok := true for j := 0; j < m; j++ { cnt := zerosum[rs[j]]-zerosum[ls[j]-1] if cnt == 0 { ok = false break } } if !ok { continue } ans = max(ans, n-zerosum[n]) } return ans } /* 考察 LからRまでに0となるBが1つ以上あるようにする必要がある Lの小さい組から拾っていき拾ったうちのどれかのRが来たらそこを0にして拾ったやつを全部破棄、という貪欲法(?)で求まる? LとRが同じ値のがあるときLを先に処理する必要がある(サンプルが優しい) */