#![allow(non_snake_case)] fn main(){ get_time(); let mut IO=IO::new(); solve(&mut IO); } // softmaxで頑張るのが良さそうだが // 係数がわかっているときに最適な戦略がわかるのか // 最後は全力投入で良い // 金をどれくらい残しておけばいいのか fn solve(IO:&mut IO){ loop{ IO.write(&[0;N]); IO.read(); } } #[derive(Clone,Copy,Default)] struct Store{ P:i64, // 人気度 rest:i64, // 残り在庫数 D:f64, // 売れやすさの隠れパラメータ } impl Store{ fn weight(&self)->f64{ 1.05f64.powi(self.P as i32)*self.D } // n冊入荷させたらどれくらい売れると予測されるのか fn predict(&self,n:i64)->f64{ let ret=(n as f64).sqrt()*self.weight(); ret.min(n as f64) } } const MONEY:i64=2000000; const TURN:usize=52; const N:usize=10; struct IO{ scan:Scanner, turn:usize, money:i64, store:[Store;N], history:Vec>, score:i64, } impl IO{ fn new()->IO{ let mut scan=Scanner::new(); input!{ scan, d:(usize,usize,i64), } assert!(d==(TURN,N,MONEY)); let store=[Store{P:0,rest:0,D:1.};N]; let history=vec![vec![1.];N]; IO{ scan, turn:0, money:MONEY, store, history, score:0, } } fn read(&mut self){ input!{ self.scan, money:i64, s:[i64;N], // 売れたやつ p:[i64;N], // 人気度 r:[i64;N], // 残り } let add=s.iter().sum::(); self.score+=add; self.money+=add*1000; for i in 0..N{ // historyを更新する // min(n,n^0.5*1.05^P*D)=s[i] // n^0.5*1.05^P*D=s[i] // s[i]/(n^0.5)/(1.05^P)=D let mut d=s[i] as f64/(self.store[i].rest as f64).sqrt()/1.05f64.powi(self.store[i].P as i32); d=d.clamp(0.5,1.5); self.history[i].push(d); self.store[i].P=p[i]; assert!(self.store[i].rest==s[i]+r[i]); self.store[i].rest=r[i]; self.store[i].D=self.history[i].iter().sum(); } assert!(self.money==money); self.turn+=1; if self.turn==TURN{ self.dump(); std::process::exit(0); } } fn write(&mut self,ans:&[usize]){ print!("1"); for i in 0..N{ let n=ans[i]; print!(" {}",n); self.store[i].rest+=n as i64; self.money-=n as i64*500; } assert!(0<=self.money); } fn write_ad(&mut self,level:i64){ print!("2 {}",level); self.money-=500000*2i64.pow(level as u32-1); for i in 0..N{ self.store[i].P+=level; } assert!(0<=self.money); } fn dump(&mut self){ eprintln!("score = {}",self.score); } } #[allow(unused)] fn get_time()->f64{ static mut START:f64=-1.; let time=std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64(); unsafe{ if START<0.{ START=time; } #[cfg(local)]{ (time-START)*1.6 } #[cfg(not(local))]{ time-START } } } #[macro_export] macro_rules! timer{ ()=>{ #[cfg(local)] let _timer=Timer(get_time()); } } static mut TIME:f64=0.; struct Timer(f64); impl Drop for Timer{ fn drop(&mut self){ unsafe{ TIME+=get_time()-self.0 } } } #[allow(unused)] mod rnd { static mut N:usize=0xcafef00dd15ea5e5; // 注意: 上の方のbitが0になってる pub fn next()->usize{ unsafe{ let x=N; N*=6364136223846793005; (x^x>>22)>>(22+(x>>61)) } } pub fn hash()->u64{ unsafe{ let x=N; N*=6364136223846793005; x as u64 } } pub fn nextf()->f64{ unsafe{ std::mem::transmute::(0x3ff0000000000000|(next() as u32 as u64)<<20)-1. } } pub fn range(a:usize,b:usize)->usize{ assert!(ausize{ assert!(a<=skip && skipi64{ assert!(a(list:&mut [T]){ for i in (0..list.len()).rev(){ list.swap(i,next()%(i+1)); } } } trait RandomChoice{ type Output; fn choice(&self)->&Self::Output; } impl RandomChoice for [T]{ type Output=T; fn choice(&self)->&T{ &self[rnd::next() as usize%self.len()] } } struct Scanner{ stack:std::str::SplitAsciiWhitespace<'static> } impl Scanner{ fn new()->Self{ use std::io::Read; let mut tmp=String::new(); std::io::stdin().read_to_string(&mut tmp).unwrap(); Self{stack:Box::leak(tmp.into_boxed_str()).split_ascii_whitespace()} } fn read(&mut self)->T{ self.stack.next().unwrap().parse::().unwrap_or_else(|_|panic!("parse error {}",std::any::type_name::())) } // インタラクティブ用 // fn new()->Self{ // Self{stack:"".split_ascii_whitespace()} // } // fn read(&mut self)->T{ // loop{ // if let Some(v)=self.stack.next(){ // return v.parse::().unwrap_or_else(|_|panic!("{}: parse error",std::any::type_name::())); // } // let mut tmp=String::new(); // std::io::stdin().read_line(&mut tmp).unwrap(); // assert!(!tmp.is_empty()); // self.stack=Box::leak(tmp.into_boxed_str()).split_ascii_whitespace(); // } // } } #[macro_export] macro_rules! input{ ($scan:expr $(,)?)=>{}; ($scan:expr, mut $name:ident:$t:tt $($rest:tt)*)=>{ let mut $name=read_value!($scan,$t); input!{$scan $($rest)*} }; ($scan:expr, $name:ident:$t:tt $($rest:tt)*)=>{ let $name=read_value!($scan,$t); input!{$scan $($rest)*} }; } #[macro_export] macro_rules! read_value{ ($scan:expr, ($($t:tt),*))=>{ ($(read_value!($scan, $t)),*) }; ($scan:expr, [$t:tt;$len:expr])=>{ (0..$len).map(|_|read_value!($scan,$t)).collect::>() }; ($scan:expr, [$t:tt])=>{ (0..$scan.read()).map(|_|read_value!($scan,$t)).collect::>() }; ($scan:expr, Chars)=>{ read_value!($scan,String).chars().collect::>() }; ($scan:expr, Usize1)=>{ read_value!($scan,usize)-1 }; ($scan:expr, $t:ty)=>{ $scan.read::<$t>() }; }