use std::io::Read; use std::collections::{HashMap, HashSet}; fn solve(n: usize, x: Vec>, a: Vec) { //0: 未, 1:済 let mut dp: HashMap = HashMap::new(); dp.insert(format!("{:0>1$b}", 0, n), 0); while !(dp.len() == 1 && dp.contains_key(&format!("{:0>1$b}", 2usize.pow(n as u32)-1, n))) { let old: HashMap = dp.clone().to_owned(); dp.clear(); for (used, min_cost) in old { used.chars().enumerate().for_each(|pair| { match pair.1 { '0' => { let mut cost: usize = 0; let mut to_1: HashSet = HashSet::new(); for f2c in x[pair.0].iter().zip(used.chars()).enumerate() { if (f2c.1).0 == &1 && (f2c.1).1 == '0' { cost += a[f2c.0]; to_1.insert(f2c.0); } } let next_str = used.clone().to_owned(); let next_str = next_str.chars().enumerate() .map(|ic| { if pair.0 == ic.0 || to_1.contains(&ic.0) { "1".to_string() } else { (ic.1).to_string() } }) .collect::>() .join(""); if let Some(costs) = dp.get_mut(&next_str) { *costs = std::cmp::min(*costs, min_cost + cost); } else { dp.insert(next_str, min_cost + cost); } }, _ => { if used == format!("{:0>1$b}", 2usize.pow(n as u32)-1, n) { let next_str = used.clone().to_owned(); if let Some(costs) = dp.get_mut(&next_str) { *costs = std::cmp::min(*costs, min_cost); } else { dp.insert(next_str, min_cost); } } }, } }); } } println!("{}", dp.get(&format!("{:0>1$b}", 2usize.pow(n as u32)-1, n)).unwrap()); } fn main() { let mut all_data = String::new(); std::io::stdin().read_to_string(&mut all_data).ok(); let all_data: Vec<&str> = all_data.trim().split('\n').map(|i| i.trim()).collect(); let n: usize = all_data.iter().next().unwrap().parse::().unwrap(); let x: Vec> = all_data.iter().skip(1).take(n).map(|i| i.split_whitespace().map(|j| j.parse::().unwrap()).collect()).collect(); let a: Vec = all_data.iter().skip(n+1).next().unwrap().split_whitespace().map(|i| i.parse::().unwrap()).collect(); solve(n, x, a); }