結果

問題 No.2390 Udon Coupon (Hard)
ユーザー 👑 MizarMizar
提出日時 2023-06-28 01:52:10
言語 Rust
(1.77.0 + proconio)
結果
TLE  
実行時間 -
コード長 2,622 bytes
コンパイル時間 13,150 ms
コンパイル使用メモリ 383,268 KB
実行使用メモリ 10,624 KB
最終ジャッジ日時 2024-07-19 03:11:27
合計ジャッジ時間 26,040 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
10,624 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 4 ms
5,376 KB
testcase_04 AC 4 ms
5,376 KB
testcase_05 AC 0 ms
5,376 KB
testcase_06 AC 0 ms
5,376 KB
testcase_07 AC 1 ms
5,376 KB
testcase_08 AC 1 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 1 ms
5,376 KB
testcase_11 AC 1 ms
5,376 KB
testcase_12 AC 1 ms
5,376 KB
testcase_13 AC 1 ms
5,376 KB
testcase_14 AC 1 ms
5,376 KB
testcase_15 AC 0 ms
5,376 KB
testcase_16 AC 1 ms
5,376 KB
testcase_17 AC 1 ms
5,376 KB
testcase_18 AC 1 ms
5,376 KB
testcase_19 AC 1 ms
5,376 KB
testcase_20 AC 1 ms
5,376 KB
testcase_21 AC 1 ms
5,376 KB
testcase_22 AC 4 ms
5,376 KB
testcase_23 AC 3 ms
5,376 KB
testcase_24 AC 1,697 ms
5,376 KB
testcase_25 AC 1,885 ms
6,948 KB
testcase_26 AC 1,755 ms
5,376 KB
testcase_27 AC 1,853 ms
6,940 KB
testcase_28 AC 1,533 ms
5,376 KB
testcase_29 TLE -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
testcase_41 -- -
testcase_42 -- -
testcase_43 -- -
testcase_44 -- -
testcase_45 -- -
testcase_46 -- -
testcase_47 -- -
testcase_48 -- -
testcase_49 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

// O(A^3)解法 (TLE想定)
// mod2048でDP配列を循環させてMLEを回避する手法
fn solve(n: u64, ab: [(u64, u64); 3]) -> u64 {
    let (a_min, a_max, b_min, b_max) = ab.iter().fold((!0u64, 0u64, !0u64, 0u64), |(a_min, a_max, b_min, b_max), &(a, b)| (a.min(a_min), a.max(a_max), b.min(b_min), b.max(b_max)));
    assert!(n > 0 && a_min > 0 && a_max < 2048 && b_min > 0);
    assert!((n / a_min).saturating_mul(b_max) < (1u64 << 61));
    let a_lcm = ab
        .iter()
        .map(|e| e.0)
        .reduce(|a, b| a / gcd(a, b) * b)
        .unwrap();
    let mut dp = [i64::MIN; 2048];
    dp[0] = 0;
    let mut v = 0;
    if n <= a_lcm {
        for i in 1..=n {
            for &(a, b) in ab.iter() {
                v.chmax(dp[(i.wrapping_sub(a) & 2047) as usize] + (b as i64));
            }
            dp[(i & 2047) as usize] = v;
        }
    } else {
        for i in 1..=a_lcm {
            for &(a, b) in ab.iter() {
                v.chmax(dp[(i.wrapping_sub(a) & 2047) as usize] + (b as i64));
            }
            dp[(i & 2047) as usize] = v;
        }
        let v_lcm = v;
        for i in a_lcm..=((n % a_lcm) + a_lcm) {
            for &(a, b) in ab.iter() {
                v.chmax(dp[(i.wrapping_sub(a) & 2047) as usize] + (b as i64));
            }
            dp[(i & 2047) as usize] = v;
        }
        v += v_lcm * ((n / a_lcm - 1) as i64);
    }
    v as u64
}

fn main() {
	let mut stdinlock = std::io::stdin().lock();
	let mut lines = std::io::BufRead::lines(&mut stdinlock);
	let n = lines.next().unwrap().unwrap().parse::<u64>().unwrap();
	let ab = (0..3).map(|_| {
		let s = lines.next().unwrap().unwrap();
		let mut t = s.split_whitespace();
		(
            t.next().unwrap().parse::<u64>().unwrap(),
            t.next().unwrap().parse::<u64>().unwrap(),
		)
	}).collect::<Vec<_>>();
    println!("{}", solve(n, [ab[0], ab[1], ab[2]]));
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    if a == 0 || b == 0 {
        return a | b;
    }
    let (tza, tzb) = (a.trailing_zeros(), b.trailing_zeros());
    a >>= tza;
    b >>= tzb;
    let tzt = tza.min(tzb);
    while a != b {
        if a > b {
            a -= b;
            a >>= a.trailing_zeros();
        } else {
            b -= a;
            b >>= b.trailing_zeros();
        }
    }
    a << tzt
}

trait Change {
    fn chmax(&mut self, x: Self);
    fn chmin(&mut self, x: Self);
}
impl<T: PartialOrd> Change for T {
    fn chmax(&mut self, x: T) {
        if *self < x {
            *self = x;
        }
    }
    fn chmin(&mut self, x: T) {
        if *self > x {
            *self = x;
        }
    }
}
0