結果

問題 No.42 貯金箱の溜息
ユーザー atn112323atn112323
提出日時 2017-01-03 10:46:23
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 36 ms / 5,000 ms
コード長 1,423 bytes
コンパイル時間 621 ms
コンパイル使用メモリ 53,992 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-08-22 10:12:52
合計ジャッジ時間 1,014 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 25 ms
4,376 KB
testcase_01 AC 36 ms
4,380 KB
testcase_02 AC 35 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>

using namespace std;

const long long MOD = 1000000009;
const int MAX = 5000;
const long long COIN[] = {1, 5, 10, 50, 100, 500};

int T;
long long M;
long long dp[MAX];

long long extgcd(long long a, long long b, long long* x, long long* y) {
	long long d = b;
	if (a == 0) {
		*x = 0; *y = 1;
	} else {
		d = extgcd(b % a, a, x, y);
		long long tmp = *x;
		*x = *y - (b / a) * *x;
		*y = tmp;
	}
	return d;
}

long long mod_inverse(long long a, long long mod) {
	long long x, y;
	extgcd(a, mod, &x, &y);
	return (mod + x) % mod;
}

int main() {
	dp[0] = 1;
	int max_coin = 0;
	int coin_count = 0;
	for (const int& coin : COIN) {
		max_coin = max(max_coin, coin);
		coin_count++;
		for (int j = coin; j < MAX; j++) {
			dp[j] = (dp[j] + dp[j - coin]) % MOD;
		}
	}
	cin >> T;
	for (int i = 0; i < T; i++) {
		cin >> M;
		if (M < MAX) {
			cout << dp[M] << endl;
		} else {
			long long q = M / max_coin;
			long long r = M % max_coin;
			long long res = 0;
			for (int j = 0; j < coin_count; j++) {
				long long term = 1;
				for (int k = 0; k < coin_count; k++) {
					if (k != j) {
						term = (term * ((q - k + MOD) % MOD)) % MOD;
					}
				}
				for (int k = 0; k < coin_count; k++) {
					if (k != j) {
						term = (term * mod_inverse((j - k + MOD) % MOD, MOD)) % MOD;
					}
				}
				res = (res + (term * dp[(j * max_coin + r)]) % MOD) % MOD;
			}
			cout << res << endl;
		}
	}
	return 0;
}
0