Submission #67897859


Source Code Expand

Copy
#include <stdio.h>
#if 0
#if 0
#define KI_MAX 4096
void ki_set(int* ki, int pos, int value) {
pos += KI_MAX - 1;
ki[pos] = value;
do {
int a, b;
pos = (pos - 1) / 2;
a = ki[pos * 2 + 1];
b = ki[pos * 2 + 2];
ki[pos] = a >= b ? a : b;
} while (pos > 0);
}
int ki_get_i(const int* ki, int idx, int ss, int se, int qs, int qe) {
if (qs <= ss && se <= qe) { /* */
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <stdio.h>

#if 0

#if 0
#define KI_MAX 4096

void ki_set(int* ki, int pos, int value) {
	pos += KI_MAX - 1;
	ki[pos] = value;
	do {
		int a, b;
		pos = (pos - 1) / 2;
		a = ki[pos * 2 + 1];
		b = ki[pos * 2 + 2];
		ki[pos] = a >= b ? a : b;
	} while (pos > 0);
}

int ki_get_i(const int* ki, int idx, int ss, int se, int qs, int qe) {
	if (qs <= ss && se <= qe) { /* セグメントがクエリに完全に含まれる */
		return ki[idx];
	} else if (se <= qs || qe <= ss) { /* 完全に外れている */
		return 0;
	} else {
		int sm = ss + (se - ss) / 2;
		int l = ki_get_i(ki, idx * 2 + 1, ss, sm, qs, qe);
		int r = ki_get_i(ki, idx * 2 + 2, sm, se, qs, qe);
		return l >=r ? l : r;
	}
}

int ki_get(const int* ki, int qs, int qe) {
	return ki_get_i(ki, 0, 0, KI_MAX, qs, qe);
}

int kis[3123][KI_MAX * 2 - 1];
#else
int maryoku_tairyoku[3123][3123];
#endif

int N, H, M;
int A[3123], B[3123];

int memo[3123][3123];
int memo_maryoku[3123][3123];

int calc(int pos, int tairyoku, int maryoku) {
	int ans = 0;
	if (pos >= N) return 0;
	if (memo[pos][tairyoku]) {
		if (maryoku == memo_maryoku[pos][tairyoku]) return ~memo[pos][tairyoku];
		if (maryoku < memo_maryoku[pos][tairyoku]) return 0;
	}
	/* 上位互換性判定 */
#if 0
	if (ki_get(kis[pos], tairyoku, H + 1) > maryoku) return 0;
#else
	if (maryoku_tairyoku[pos][maryoku] > tairyoku) return 0;
#endif
	if (A[pos] <= tairyoku) {
		int candidate = calc(pos + 1, tairyoku - A[pos], maryoku) + 1;
		if (candidate > ans) ans = candidate;
	}
	if (B[pos] <= maryoku) {
		int candidate = calc(pos + 1, tairyoku, maryoku - B[pos]) + 1;
		if (candidate > ans) ans = candidate;
	}
#if 0
	ki_set(kis[pos], tairyoku, maryoku);
#else
	maryoku_tairyoku[pos][maryoku] = tairyoku;
#endif
	memo_maryoku[pos][tairyoku] = maryoku;
	return ~(memo[pos][tairyoku] = ~ans);
}

int main(void) {
	int i;
	if (scanf("%d%d%d", &N, &H, &M) != 3) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%d", &A[i], &B[i]) != 2) return 1;
	}
	printf("%d\n", calc(0, H, M));
	return 0;
}

#else

#include <string.h>

void chmax(int* target, int candidate) {
	if (*target < candidate) *target = candidate;
}

int N, H, M;
int A[3123], B[3123];

int max_maryoku[3123][3123];

int main(void) {
	int i;
	int ans = 0;
	if (scanf("%d%d%d", &N, &H, &M) != 3) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%d", &A[i], &B[i]) != 2) return 1;
	}
	memset(max_maryoku, -1, sizeof(max_maryoku));
	max_maryoku[0][H] = M;
	for (i = 0; i < N; i++) {
		int j;
		for (j = 0; j <= H; j++){
			if (max_maryoku[i][j] >= 0) {
				ans = i; /* 最終到達点を求める */
				/* 魔法を使わずに戦う */
				if (j >= A[i]) {
					chmax(&max_maryoku[i + 1][j - A[i]], max_maryoku[i][j]);
				}
				/* 魔法を使って戦う */
				if (max_maryoku[i][j] >= B[i]) {
					chmax(&max_maryoku[i + 1][j], max_maryoku[i][j] - B[i]);
				}
			}
		}
	}
	for (i = 0; i <= H; i++) {
		if (max_maryoku[N][i] >= 0) ans = N;
	}
	printf("%d\n", ans);
	return 0;
}

#endif

/*

[位置][体力][魔力]でメモ化探索をしたい → そのままやると死にそう
各位置で必ず体力か魔力を削るので、魔力は位置と体力から一意に決まる → 省略可
↑嘘 Aが同じでBが異なる敵が居た場合、どっちを魔力でやったかわからない

メモと一緒にそのときの魔力も書いておく
新しい探索の際の魔力が
多い → 探索をしなおす
同じ → メモの値を返す
少ない → 上位互換の状態で来れるはず、無駄なので0を返す
これでWAは回避できるかもだけど、計算量どやろ……?
↓
以下のコードで作ったランダムケースで2.8sだった 厳しそう

#include <stdio.h>

static unsigned int x=123456789;
static unsigned int y=362436069;
static unsigned int z=521288629;
static unsigned int w=88675123;

unsigned int randint(void) {
	unsigned int t;
	t = (x ^ (x << 11));
	x = y; y = z; z = w;
	w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
	return w;
}

int main(void) {
	int i;
	puts("3000 3000 3000");
	for (i = 0; i < 3000; i++) {
		unsigned int a = randint() % 50 + 1;
		unsigned int b = randint() % 50 + 1;
		printf("%u %u\n", a, b);
	}
	return 0;
}

魔力ごとにその魔力での最大体力も書いておく → 上位互換性判定
体力・魔力ともに上回るケースがあるかも知りたい → セグ木

→ セグ木使ったらむしろクソ時間かかった
その魔力だけの判定に → 2.6s あまり効かない

-----------

「上位互換性」をより活用するため、深さ優先探索から幅優先探索に切り替える
各階層の各体力ごとに、魔力が最大の条件だけ次に進む
→ 各階層で高々H+1パターンになり、いけそう

各階層に来たときの各体力について、実現できる最大の魔力を求める

*/

Submission Info

Submission Time
Task E - Battles in a Row
User mikecat
Language C (gcc 12.2.0)
Score 450
Code Size 5049 Byte
Status AC
Exec Time 25 ms
Memory 39872 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 450 / 450
Status
AC × 3
AC × 40
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, random_24.txt, random_25.txt, random_26.txt, random_27.txt, random_28.txt, random_29.txt, random_30.txt, random_31.txt, random_32.txt, random_33.txt, random_34.txt, random_35.txt, random_36.txt, random_37.txt, sample_01.txt, sample_02.txt, sample_03.txt
Case Name Status Exec Time Memory
random_01.txt AC 20 ms 39716 KiB
random_02.txt AC 21 ms 39852 KiB
random_03.txt AC 20 ms 39844 KiB
random_04.txt AC 18 ms 39848 KiB
random_05.txt AC 19 ms 39856 KiB
random_06.txt AC 18 ms 39744 KiB
random_07.txt AC 23 ms 39764 KiB
random_08.txt AC 22 ms 39844 KiB
random_09.txt AC 23 ms 39844 KiB
random_10.txt AC 20 ms 39708 KiB
random_11.txt AC 20 ms 39764 KiB
random_12.txt AC 20 ms 39748 KiB
random_13.txt AC 16 ms 39820 KiB
random_14.txt AC 17 ms 39832 KiB
random_15.txt AC 21 ms 39872 KiB
random_16.txt AC 18 ms 39696 KiB
random_17.txt AC 18 ms 39832 KiB
random_18.txt AC 17 ms 39816 KiB
random_19.txt AC 18 ms 39848 KiB
random_20.txt AC 18 ms 39872 KiB
random_21.txt AC 20 ms 39820 KiB
random_22.txt AC 17 ms 39720 KiB
random_23.txt AC 18 ms 39756 KiB
random_24.txt AC 19 ms 39708 KiB
random_25.txt AC 16 ms 39852 KiB
random_26.txt AC 16 ms 39728 KiB
random_27.txt AC 16 ms 39692 KiB
random_28.txt AC 16 ms 39808 KiB
random_29.txt AC 15 ms 39740 KiB
random_30.txt AC 15 ms 39832 KiB
random_31.txt AC 22 ms 39752 KiB
random_32.txt AC 21 ms 39772 KiB
random_33.txt AC 25 ms 39856 KiB
random_34.txt AC 25 ms 39748 KiB
random_35.txt AC 25 ms 39724 KiB
random_36.txt AC 25 ms 39728 KiB
random_37.txt AC 25 ms 39712 KiB
sample_01.txt AC 15 ms 39740 KiB
sample_02.txt AC 16 ms 39688 KiB
sample_03.txt AC 16 ms 39760 KiB


2025-07-26 (Sat)
07:01:57 +09:00