package main import . "fmt" import . "os" import bf "bufio" import "math/rand" func main() { rd := bf.NewReader(Stdin) var n int Fscan(rd,&n) a := make([]int, n) for i := range a { Fscan(rd, &a[i]) } ans := solve1(n, a) Println(ans) } func solve1(n int, a []int) int { dp := make([]int, 10) tmp := make([]int, 10) dp[0] = 1 for _, x := range a { copy(tmp, dp) for i, c := range dp { if c > 0 { t := (i+x)%10 tmp[t] = max(tmp[t], c+1) } } dp,tmp = tmp,dp } return dp[0]-1 } func solve2(n int, a []int) int { table := make([]int, 10) sum := 0 for _, x := range a { table[x%10]++ sum = (sum+x)%10 } if sum == 0 { return n } dp := make([][]bool, 10) for i := range dp { dp[i] = make([]bool, 10) } dp[0][0] = true for i := 1; i < 10; i++ { if table[i] == 0 { continue } for c := 8; c >= 0; c-- { for k := 1; k <= table[i] && c+k <= 9; k++ { for j := 0; j < 10; j++ { if dp[c][j] { dp[c+k][(j+k*i)%10] = true } } } } } for i := 1; i < 10; i++ { if dp[i][sum%10] { return n - i } } return 0 } func init() { check() } func check() { for t := 0; t < 10000; t++ { n := rand.Intn(500)+30 a := make([]int, n) for i := range a { a[i] = rand.Intn(100)+1 } ans1 := solve1(n, a) ans2 := solve2(n, a) if ans1 != ans2 { println("n=",n) println("a=",Sprint(a)) println("ans1=",ans1) println("ans2=",ans2) panic("wrong") } } } /* 考察 mod 10 で数え上げDPかなあ・・・わからん DP[i枚目][sum(A0...Ai) mod 10] = 最大使用枚数 とか? あるいは Aの総和のmod 10が0にならない場合 その端数分を引き算で除去できる最小の枚数を求める・・・とか? 例えば sum(A) = 1 (mod 10) なら 1枚で1 (mod 10)になるカード 2枚の和で 1 (mod 10) になる組み合わせのカード ... 9枚の和で 1 (mod 10) になる組み合わせのカード を見つければよい…? DP[枚数][? (mod 10)] = 存在する(1)か否(0)か これそのままA全体に対してやっちゃうとTLEしそうなので Aを事前にmod 10で分類して枚数で管理すれば10^3程度の計算で済む? 入力のデータ個数が2e5を超えるとbufio使わないと入力読み込むだけでTLEするのつらい IOでのTLEはつらい */