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 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 ----------
// ---------- begin Precalc ----------
#[allow(dead_code)]
struct Precalc {
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            fact[i] = fact[i - 1] * ModInt(i as u32);
        }
        ifact[n] = fact[n].inv();
        if n > 0 {
            inv[n] = ifact[n] * fact[n - 1];
        }
        for i in (1..n).rev() {
            ifact[i] = ifact[i + 1] * ModInt((i + 1) as u32);
            inv[i] = ifact[i] * fact[i - 1];
        }
        Precalc {
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn inv(&self, n: usize) -> ModInt {
        assert!(n > 0);
        self.inv[n]
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
}
// ---------- end Precalc ----------

use proconio::marker::*;
use proconio::*;
use std::cmp::*;

// 先頭の1, 末尾の0を削除した文字列でOK
// 同じ1を2回以上操作するのは1回にまとめられるのでk <= |S| としてよい
//
// [操作回数][保持する1]　だと重複が発生する
// 直前に操作したかも持っておく

#[fastout]
fn run() {
    input! {
        s: Chars,
        k: usize,
    }
    let n = s.len();
    let k = std::cmp::min(k, n - 1);
    let mut a = vec![];
    for c in s {
        match c {
            '0' => a.push((c, 1)),
            '1' => {
                if a.last().map_or(false, |a| a.0 == '1') {
                    a.last_mut().unwrap().1 += 1;
                } else {
                    a.push((c, 1));
                }
            }
            _ => (),
        }
    }
    // [操作回数][保持してる1][直前に挿入したなら1]
    let mut dp = vec![vec![vec![ModInt::zero(); 2]; n + 1]; n + 1];
    dp[0][0][0] = ModInt::one();
    for (d, c) in a.into_iter().rev() {
        let mut next = vec![vec![vec![ModInt::zero(); 2]; n + 1]; n + 1];
        if d == '1' {
            for i in 0..=n {
                for j in 0..=i {
                    for k in 0..2 {
                        let v = dp[i][j][k];
                        if v.0 == 0 {
                            continue;
                        }
                        if k == 1 {
                            next[i][j][0] += v;
                            next[i + 1][j + 1][0] -= v;
                        } else {
                            next[i][j][0] += v;
                            let r = min(n - 1, i + c);
                            next[r + 1][j + r + 1 - i][0] -= v;
                        }
                        /*
                        if k == 1 {
                            next[i][j][0] += v;
                        } else {
                            for x in i..=min(n, i + c) {
                                next[x][j + x - i][0] += v;
                            }
                        }
                        */
                    }
                }
            }
            for i in 1..=n {
                for j in 1..=n {
                    for k in 0..2 {
                        next[i][j][k] = next[i][j][k] + next[i - 1][j - 1][k];
                    }
                }
            }
        } else {
            for i in 0..=n {
                for j in 0..=i {
                    for k in 0..2 {
                        let v = dp[i][j][k];
                        if v.0 == 0 {
                            continue;
                        }
                        next[i][0][1] += v;
                        next[i][j][1] -= v;
                        next[i][j][0] += v;
                        next[i][j + 1][0] -= v;
                        /*
                        for x in 0..=j {
                            let y = if x == j {0} else {1};
                            next[i][x][y] += v;
                        }
                        */
                    }
                }
            }
            for i in 0..=n {
                for j in 1..=n {
                    for k in 0..2 {
                        next[i][j][k] = next[i][j][k] + next[i][j - 1][k];
                    }
                }
            }
        }
        dp = next;
    }
    let mut ans = ModInt::zero();
    for i in 0..=k {
        ans += dp[i][0][0] + dp[i][0][1];
    }
    println!("{}", ans);
}

fn main() {
    run();
}