Problem:
Score : 800 points

Problem Statement

Given is a string S consisting of 0 and 1. Find the number of strings, modulo 998244353, that can result from applying the following operation on S between 0 and K times (inclusive):

Choose a pair of integers i, j (1\leq i < j\leq |S|) such that the i-th and j-th characters of S are 0 and 1, respectively. Remove the j-th character from S and insert it to the immediate left of the i-th character.

Constraints

1 \leq |S| \leq 300

0 \leq K \leq 10^9

S consists of 0 and 1.

Input

Input is given from Standard Input in the following format:

S K

Output

Find the number of strings, modulo 998244353, that can result from applying the operation on S between 0 and K times (inclusive).

Sample Input 1

0101 1

Sample Output 1

4

Four strings, 0101, 0110, 1001, and 1010, can result.

Sample Input 2

01100110 2

Sample Output 2

14

Sample Input 3

1101010010101101110111100011011111011000111101110101010010101010101 20

Sample Output 3

113434815

Solution in Go (1.14.1) (judge verdict: Accepted)

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

func main() {
	sc := NewScanner(os.Stdin)
	s, _ := sc.NextString()
	k, _ := sc.NextInt()
	ans := solve(s, k)
	fmt.Println(ans)
}

const mod = 998244353

func solve(s string, m int) (ans int) {
	count := countOnes(s)
	n := len(count)
	sum := 0
	for _, v := range count {
		sum += v
	}
	m = Min(m, sum)
	dp := initDp(m)
	dp[0][0] = 1
	for i := 0; i < n; i++ {
		tmp := initDp(m)
		for j := 0; j <= m; j++ {
			for k := 0; k <= m; k++ {
				// do nothing
				tmp[j][k] += dp[j][k]
				tmp[j][k] %= mod
				// move from stock
				for l := 1; l <= k; l++ {
					tmp[j][k-l] += dp[j][k]
					tmp[j][k-l] %= mod
				}
				// move to stock
				for l := 1; l <= count[n-1-i] && j+l <= m && k+l <= m; l++ {
					tmp[j+l][k+l] += dp[j][k]
					tmp[j+l][k+l] %= mod
				}
			}
		}
		copy(dp, tmp)
	}
	for j := range dp {
		ans += dp[j][0]
		ans %= mod
	}
	return ans
}

func countOnes(s string) []int {
	ret := []int{}
	count := 0
	for _, c := range s {
		if c == '1' {
			count++
			continue
		}
		ret = append(ret, count)
		count = 0
	}
	ret = append(ret, count)
	return ret
}

func initDp(m int) [][]int {
	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, m+1)
	}
	return dp
}

// Scanner is a wrapper of bufio.Scanner which is customized for competitive programing.
type Scanner struct {
	bufio.Scanner
}

// NewScanner is a constructor for Scanner.
func NewScanner(r io.Reader) *Scanner {
	sc := Scanner{*bufio.NewScanner(r)}
	sc.Buffer([]byte{}, math.MaxInt64)
	sc.Split(bufio.ScanWords)
	return &sc
}

// NextInt reads a integer from io stream.
func (sc *Scanner) NextInt() (int, error) {
	if !sc.Scan() {
		return -1, errors.New("failed to scan")
	}
	return strconv.Atoi(sc.Text())
}

// NextString reads a string from io stream
func (sc *Scanner) NextString() (string, error) {
	if !sc.Scan() {
		return "", errors.New("failed to scan")
	}
	return sc.Text(), nil
}

// Min returns minimum value of inputs
func Min(a ...int) (min int) {
	for i, ai := range a {
		if i == 0 || ai < min {
			min = ai
		}
	}
	return min
}