Submission #66028988


Source Code Expand

Copy
#include <stdio.h>
#if 0
#include <stdlib.h>
int cmp(const void* x, const void* y) {
int a = *(const int*)x, b = *(const int*)y;
return a < b ? -1 : a > b;
}
#endif
int N, D;
int A[212345];
#if 0
int memo[212345];
int calc(int pos) {
int ans = N + 1, candidate;
if (pos >= N - 1) return 0;
if (memo[pos]) return ~memo[pos];
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <stdio.h>

#if 0
#include <stdlib.h>

int cmp(const void* x, const void* y) {
	int a = *(const int*)x, b = *(const int*)y;
	return a < b ? -1 : a > b;
}
#endif

int N, D;
int A[212345];

#if 0
int memo[212345];

int calc(int pos) {
	int ans = N + 1, candidate;
	if (pos >= N - 1) return 0;
	if (memo[pos]) return ~memo[pos];
	/* 飛ばす */
	if (A[pos + 1] - A[pos] <= D) {
		int no = pos + 1, yes = N;
		while (no + 1 < yes) {
			int m = no + (yes - no) / 2;
			if (A[m] - A[pos] <= D) no = m; else yes = m;
		}
		candidate = calc(yes) + (yes - pos - 1);
		if (candidate < ans) ans = candidate;
	}
	/* 飛ばさない */
	if (A[pos + 1] - A[pos] != D) {
		candidate = calc(pos + 1);
		if (candidate < ans) ans = candidate;
	}
	return ~(memo[pos] = ~ans);
}
#endif

int count[1123456 * 2];
int memo[1123456 * 2][2];
char visited[1123456 * 2];

int calc(int pos, int prev_erased) {
	int ans;
	visited[pos] = 1;
	if (count[pos] <= 0) return 0;
	if (memo[pos][prev_erased]) return ~memo[pos][prev_erased];
	/* 消す */
	ans = calc(pos + D, 1) + count[pos];
	/* 消さない */
	if (prev_erased) {
		int candidate = calc(pos + D, 0);
		if (candidate < ans) ans = candidate;
	}
	return ~(memo[pos][prev_erased] = ~ans);
}

int main(void) {
	int i;
	int ans = 0;
	if (scanf("%d%d", &N, &D) != 2) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d", &A[i]) != 1) return 1;
		count[A[i]]++;
	}
#if 0
	qsort(A, N, sizeof(*A), cmp);
	printf("%d\n", calc(0));
#endif
	if (D == 0) {
		for (i = 0; i <= 1000000; i++) {
			if (count[i] > 1) ans += count[i] - 1;
		}
	} else {
		for (i = 0; i <= 1000000; i++) {
			if (count[i] > 0 && !visited[i]) {
				ans += calc(i, 1);
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}

/*

全ての組み合わせを考える → ソートしてよい

差がDになるならそこを消せばいい? → いいえ

7 1
1 3 4 4 4 5 10

貪欲にやると 4 を消したくなるが、3 と 5 を消したほうがよい

行動を「消さない」「差がDを超えるところまで消す」から選ぶメモ化探索

↑大嘘
・「差がDを超えるところまで消す」では、1→3でD(=1)を超えるので消せない
・隣接する数値の差がD未満のとき、隣接しない数値の差がDになることがある

-----------

同じ数値はまとめる
差がDになる数値に辺を張る (それぞれの数値から高々2本しか出ない)
連結成分ごとに消す/消さないを考える

複雑な「グラフ」として考えなくても、「差がDになる」ということは等差数列である
それぞれの数列ごとに、「消す」「消さない」の行動を選んでいくメモ化探索
奇数番目/偶数番目を消す だと 2 1 1 2 (個) みたいなパターンに対応できない
「消さない」連続はダメ

*/

Submission Info

Submission Time
Task D - Forbidden Difference
User mikecat
Language C (gcc 12.2.0)
Score 425
Code Size 2942 Byte
Status AC
Exec Time 32 ms
Memory 15984 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 425 / 425
Status
AC × 3
AC × 40
Set Name Test Cases
Sample 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt
All 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 01_random_10.txt, 01_random_11.txt, 01_random_12.txt, 01_random_13.txt, 01_random_14.txt, 01_random_15.txt, 01_random_16.txt, 01_random_17.txt, 01_random_18.txt, 01_random_19.txt, 01_random_20.txt, 01_random_21.txt, 01_random_22.txt, 01_random_23.txt, 01_random_24.txt, 01_random_25.txt, 01_random_26.txt, 01_random_27.txt, 01_random_28.txt, 01_random_29.txt, 01_random_30.txt, 01_random_31.txt, 01_random_32.txt, 02_handmade_01.txt, 02_handmade_02.txt, 02_handmade_03.txt, 02_handmade_04.txt, 02_handmade_05.txt
Case Name Status Exec Time Memory
00_sample_01.txt AC 1 ms 1604 KB
00_sample_02.txt AC 1 ms 1740 KB
00_sample_03.txt AC 1 ms 1756 KB
01_random_01.txt AC 11 ms 2436 KB
01_random_02.txt AC 2 ms 1776 KB
01_random_03.txt AC 11 ms 2388 KB
01_random_04.txt AC 5 ms 1868 KB
01_random_05.txt AC 11 ms 2536 KB
01_random_06.txt AC 10 ms 2404 KB
01_random_07.txt AC 11 ms 2420 KB
01_random_08.txt AC 7 ms 2032 KB
01_random_09.txt AC 12 ms 2416 KB
01_random_10.txt AC 12 ms 2312 KB
01_random_11.txt AC 12 ms 2372 KB
01_random_12.txt AC 10 ms 2352 KB
01_random_13.txt AC 12 ms 2380 KB
01_random_14.txt AC 6 ms 2088 KB
01_random_15.txt AC 13 ms 2544 KB
01_random_16.txt AC 4 ms 1824 KB
01_random_17.txt AC 16 ms 3336 KB
01_random_18.txt AC 12 ms 2628 KB
01_random_19.txt AC 15 ms 2580 KB
01_random_20.txt AC 10 ms 2180 KB
01_random_21.txt AC 15 ms 2504 KB
01_random_22.txt AC 15 ms 2624 KB
01_random_23.txt AC 15 ms 2456 KB
01_random_24.txt AC 9 ms 3084 KB
01_random_25.txt AC 32 ms 15132 KB
01_random_26.txt AC 12 ms 14560 KB
01_random_27.txt AC 32 ms 15208 KB
01_random_28.txt AC 12 ms 14460 KB
01_random_29.txt AC 31 ms 15984 KB
01_random_30.txt AC 30 ms 15468 KB
01_random_31.txt AC 24 ms 6396 KB
01_random_32.txt AC 14 ms 14624 KB
02_handmade_01.txt AC 13 ms 2540 KB
02_handmade_02.txt AC 13 ms 2368 KB
02_handmade_03.txt AC 2 ms 1596 KB
02_handmade_04.txt AC 1 ms 1624 KB
02_handmade_05.txt AC 1 ms 1616 KB


2025-05-22 (Thu)
04:27:05 +09:00