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 Rust (1.42.0) (judge verdict: Accepted)

// ---------- begin ModInt ----------
const MOD: u32 = 998_244_353;

#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

impl From<usize> for ModInt {
    fn from(val: usize) -> ModInt {
        ModInt((val % MOD as usize) as u32)
    }
}

impl From<i64> for ModInt {
    fn from(val: i64) -> ModInt {
        let m = MOD as i64;
        ModInt::new((val % m + m) as u32)
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn is_zero(&self) -> bool {
        self.0 == 0
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        assert!(self.0 > 0);
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------

fn run() {
    proconio::input! {
        mut s: proconio::marker::Chars,
        k: usize,
    }
    for c in "01".chars() {
        while s.last().map_or(false, |p| *p == c) {
            s.pop();
        }
        s.reverse();
    }
    if s.is_empty() {
        println!("1");
        return;
    }
    let mut a = vec![];
    for c in s {
        if c == '0' {
            a.push(0);
        } else {
            *a.last_mut().unwrap() += 1;
        }
    }
    let k = std::cmp::min(k, a.iter().sum());
    // [取り出した回数][挿入した回数]
    let mut dp = vec![vec![ModInt::zero()]];
    dp[0][0] = ModInt::one();
    for a in a.into_iter().rev() {
        let len = std::cmp::min(k + 1, dp.len() + a);
        let mut next = vec![vec![ModInt::zero(); len]; len];
        // 挿入
        for (i, dp) in dp.iter().enumerate() {
            let next = &mut next[i];
            for (j, &v) in dp.iter().enumerate().filter(|p| !p.1.is_zero()) {
                next[j] += v;
                if let Some(p) = next.get_mut(i + 1) {
                    *p -= v;
                }
            }
            for j in 1..next.len() {
                next[j] = next[j] + next[j - 1];
            }
        }
        // 取り出す
        for (i, dp) in dp.iter().enumerate() {
            for (j, &v) in dp.iter().enumerate().filter(|p| !p.1.is_zero()) {
                for p in (i + 1)..=std::cmp::min(k, i + a) {
                    next[p][j] += v;
                }
            }
        }
        dp = next;
    }
    let mut ans = ModInt::zero();
    for dp in dp {
        for a in dp {
            ans += a;
        }
    }
    println!("{}", ans);
}

fn main() {
    run();
}