Submission #1005441


Source Code Expand

//・「高橋君は同じ種類の硬貨を9枚までしか持てない」としても最適性を失わない。
//
//f(k) = {({A}の部分和 / (10^k)) % 10}の最大値, とするとΣf(k)が答え。
//(注意:X / (10^k)が分かってても, (X+Y) / (10^k)は分からないので、{({A}の部分和 / (10^k)) % 10}自体を持って探索するのは無理そう。)

//例えば、8 * 10^k <= {A}の部分和 % (10^(k+1)) < 9 * 10^kを満たす{A}の部分和が存在するなら「10^k円玉を8枚使う場合」が存在する。
//例えば、1000円玉を8枚使う場合、支払う金額は「*8???円」となっている。(金額→枚数, ではなく, 枚数→金額を考えるのがミソ)
//
//よって, 各整数1 <= k < 17, 0 <= d < 10について、{A}の部分和 % (10^(k+1))を、10^k * d以上 10^k * (d + 1)未満にできるか「高速に」判定できればよい。
//(その判定結果をis_ok(k, d)とおくと、f(k) = is_ok(k, d)がtrueになるdの最大値, だから)
//
//これを解くには、dp[番号][今までの和]というDPがヒントになるが、これでは解けないので、逆算を考える。
//
//実は
//{X_1,…,X_N}の部分和を[L, R)にできる⇔{X2,…,X_N}の部分和を[L, R) or [L - X1, R - X1)にできる, が成り立ち, これを今回の問題で使うなら
//{X_1,…,X_N}の部分和(mod M)を[L, R)にできる ⇔ {X2,…,X_N}の部分和(mod M)を[L, R) or [(L - X1) mod M, (R - X1) mod M)にできる
//
//今回は[L, R)がM / 10以上なので、dp[i][j] = {{A_i, …, A_N}の部分和がjになればOKな状態} (trueならそうなってて, falseならそうなってない)
//とおくと、dp[i][j] = trueとなるjは、10個以下の「互いに重ならない」区間で表すことができる。
//
//例えば、部分和を{8000~9999}にすればOKな場合を考える。
//値500を選んだら、残り部分和  = {7500 ~ 9499}にすればよく, 無視すれば、残り要素和 = {8000~9999}にすればよくなる。
//つまり、値500の(取る, 取らない)を決めたときに、残り部分和は{7500~9999}の範囲に収めればよい。
//値2530を選んだら、残り部分和 = 5470 ~ 7469にすればよく、無視すれば = {8000~9999}…
//結局、残り部分和 を「5470~7469, 8000~9999」の範囲に収めればよい。
//
//オートマトンの同形判定とか知ってるとこういうDPは立てやすいし、DPを立てる前後の話は素朴。
//「なんでこういう式を立てたのか?」, 「もう一つ方針があるけど、どっちが良さそう? (同値な3つの条件から1つを選んで解くあれ)」を考えるだけで解ける。
//(思い込みはよくないということが分かる良問)(chokudai(敬称略)は天才)
//でも実装きつかったw

#include <iostream>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;

int n;
int a[20000];
int power[18];

bool is_ok(int k, int d) {
	static int low[20001][15];
	static int high[20001][15];
	static int seg_cnt[20001];
	static int b[20000];
	int i, j;
	
	for (i = 0; i < n; i++) { b[i] = a[i] % power[k + 1]; }
	for (i = 0; i < n; i++) { b[i] = power[k + 1] - b[i]; }
	
	low[0][0] = d * power[k];
	high[0][0] = (d + 1) * power[k] - 1;
	seg_cnt[0] = 1;
	
	//cout << "k = " << k << " " << " d = " << d << endl;
	
	for (i = 0; i < n; i++) {
		static int nlow[30], nhigh[30];
		
		for (j = 0; j < seg_cnt[i]; j++) {
			int p = (low[i][j] + b[i]) % power[k + 1];
			int q = (high[i][j] + b[i]) % power[k + 1];
			
			if (p > q || p == 0 || q == 0) {
				return true;
			}
			
			else {
				nlow[2 * j]      = p;
				nhigh[2 * j]     = q;
			}
			
			nlow[2 * j + 1]  = low[i][j];
			nhigh[2 * j + 1] = high[i][j];
		}
		
		//2 * seg_cnt個の(同じ長さの)閉区間をマージする
		static pair<int, int> seg[30];
		for (j = 0; j < seg_cnt[i] * 2; j++) { seg[j] = pair<int, int>(nlow[j], nhigh[j]); }
		sort(seg, seg + seg_cnt[i] * 2);
		
		int id = 0;
		seg_cnt[i + 1] = 0;

		for (j = 0; j < seg_cnt[i] * 2; j++) {
			//cout << "seg ; " << seg[j].first << " " << seg[j].second << ", ";
			if (seg[j].first - seg[id].second >= 2) {
				low[i + 1][seg_cnt[i + 1]] = seg[id].first;
				high[i + 1][seg_cnt[i + 1]] = seg[j-1].second;
				seg_cnt[i + 1]++;
				id = j;
			}
		}
		//cout << endl;
		low[i + 1][seg_cnt[i + 1]] = seg[id].first;
		high[i + 1][seg_cnt[i + 1]] = seg[j-1].second;
		seg_cnt[i + 1]++;
	}
	
	/*for (i = 0; i <= n; i++) {
		for (j = 0; j < seg_cnt[i]; j++) {
			cout << "[" << low[i][j] << ", " << high[i][j] << "]";
			if (j + 1 < seg_cnt[i]) { cout << " or "; }
		}
		cout << endl;
	}*/
		
	for (i = 0; i < seg_cnt[n]; i++) {
		if (low[n][i] <= 0 && 0 <= high[n][i]) {
			return true;
		}
	}
	return false;
}

signed main() {
	power[0] = 1;
	for (int i = 1; i < 18; i++) { power[i] = power[i - 1] * 10; }
	
	cin >> n;
	for (int i = 0; i < n; i++) { cin >> a[i]; }
	
	int ans = 0;
	for (int i = 0; i < 17; i++) {
		for (int d = 9; d >= 1; d--) {
			if (is_ok(i, d)) {
				ans += d;
				break;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

Submission Info

Submission Time
Task B - Exact Payment
User startcpp
Language C++14 (GCC 5.4.1)
Score 1500
Code Size 5321 Byte
Status AC
Exec Time 138 ms
Memory 5376 KB

Judge Result

Set Name sample All
Score / Max Score 0 / 0 1500 / 1500
Status
AC × 2
AC × 100
Set Name Test Cases
sample sample-01.txt, sample-02.txt
All sample-01.txt, sample-02.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 01-12.txt, 01-13.txt, 01-14.txt, 01-15.txt, 01-16.txt, 01-17.txt, 01-18.txt, 01-19.txt, 01-20.txt, 01-21.txt, 01-22.txt, 01-23.txt, 01-24.txt, 01-25.txt, 01-26.txt, 01-27.txt, 01-28.txt, 01-29.txt, 01-30.txt, 01-31.txt, 01-32.txt, 01-33.txt, 01-34.txt, 01-35.txt, 01-36.txt, 01-37.txt, 01-38.txt, 01-39.txt, 01-40.txt, 01-41.txt, 01-42.txt, 01-43.txt, 01-44.txt, 01-45.txt, 01-46.txt, 01-47.txt, 01-48.txt, 01-49.txt, 01-50.txt, 01-51.txt, 01-52.txt, 01-53.txt, 01-54.txt, 01-55.txt, 01-56.txt, 01-57.txt, 01-58.txt, 01-59.txt, 01-60.txt, 01-61.txt, 01-62.txt, 01-63.txt, 01-64.txt, 01-65.txt, 01-66.txt, 01-67.txt, 01-68.txt, 01-69.txt, 01-70.txt, 01-71.txt, 01-72.txt, 01-73.txt, 01-74.txt, 01-75.txt, 01-76.txt, 01-77.txt, 01-78.txt, 01-79.txt, 01-80.txt, 01-81.txt, 01-82.txt, 01-83.txt, 01-84.txt, 01-85.txt, 01-86.txt, 01-87.txt, 01-88.txt, 01-89.txt, 01-90.txt, 01-91.txt, 01-92.txt, 01-93.txt, 01-94.txt, 01-95.txt, 01-96.txt, 01-97.txt, 01-98.txt
Case Name Status Exec Time Memory
01-01.txt AC 3 ms 256 KB
01-02.txt AC 3 ms 256 KB
01-03.txt AC 3 ms 256 KB
01-04.txt AC 3 ms 256 KB
01-05.txt AC 3 ms 256 KB
01-06.txt AC 33 ms 5376 KB
01-07.txt AC 36 ms 5376 KB
01-08.txt AC 43 ms 5376 KB
01-09.txt AC 46 ms 5376 KB
01-10.txt AC 72 ms 5376 KB
01-11.txt AC 67 ms 5376 KB
01-12.txt AC 41 ms 5376 KB
01-13.txt AC 41 ms 5376 KB
01-14.txt AC 37 ms 5376 KB
01-15.txt AC 40 ms 5376 KB
01-16.txt AC 51 ms 5376 KB
01-17.txt AC 42 ms 5376 KB
01-18.txt AC 39 ms 5376 KB
01-19.txt AC 42 ms 5376 KB
01-20.txt AC 42 ms 5376 KB
01-21.txt AC 42 ms 5376 KB
01-22.txt AC 38 ms 5376 KB
01-23.txt AC 40 ms 5376 KB
01-24.txt AC 44 ms 5376 KB
01-25.txt AC 40 ms 5376 KB
01-26.txt AC 38 ms 5376 KB
01-27.txt AC 40 ms 5376 KB
01-28.txt AC 35 ms 5376 KB
01-29.txt AC 45 ms 5376 KB
01-30.txt AC 41 ms 5376 KB
01-31.txt AC 40 ms 5376 KB
01-32.txt AC 45 ms 5376 KB
01-33.txt AC 41 ms 5376 KB
01-34.txt AC 42 ms 5376 KB
01-35.txt AC 40 ms 5376 KB
01-36.txt AC 41 ms 5376 KB
01-37.txt AC 35 ms 5376 KB
01-38.txt AC 39 ms 5376 KB
01-39.txt AC 41 ms 5376 KB
01-40.txt AC 39 ms 5376 KB
01-41.txt AC 40 ms 5376 KB
01-42.txt AC 42 ms 5376 KB
01-43.txt AC 41 ms 5376 KB
01-44.txt AC 38 ms 5376 KB
01-45.txt AC 38 ms 5376 KB
01-46.txt AC 38 ms 5376 KB
01-47.txt AC 36 ms 5376 KB
01-48.txt AC 37 ms 5376 KB
01-49.txt AC 36 ms 5376 KB
01-50.txt AC 37 ms 5376 KB
01-51.txt AC 37 ms 5376 KB
01-52.txt AC 31 ms 5376 KB
01-53.txt AC 36 ms 5376 KB
01-54.txt AC 33 ms 5376 KB
01-55.txt AC 37 ms 5376 KB
01-56.txt AC 36 ms 5376 KB
01-57.txt AC 37 ms 5376 KB
01-58.txt AC 33 ms 5376 KB
01-59.txt AC 35 ms 5376 KB
01-60.txt AC 36 ms 5376 KB
01-61.txt AC 36 ms 5376 KB
01-62.txt AC 35 ms 5376 KB
01-63.txt AC 37 ms 5376 KB
01-64.txt AC 35 ms 5376 KB
01-65.txt AC 35 ms 5376 KB
01-66.txt AC 138 ms 5376 KB
01-67.txt AC 62 ms 5376 KB
01-68.txt AC 49 ms 5376 KB
01-69.txt AC 52 ms 5376 KB
01-70.txt AC 46 ms 5376 KB
01-71.txt AC 90 ms 5376 KB
01-72.txt AC 94 ms 5376 KB
01-73.txt AC 99 ms 5376 KB
01-74.txt AC 112 ms 5376 KB
01-75.txt AC 108 ms 5376 KB
01-76.txt AC 126 ms 5376 KB
01-77.txt AC 50 ms 5376 KB
01-78.txt AC 93 ms 5376 KB
01-79.txt AC 82 ms 5376 KB
01-80.txt AC 87 ms 5376 KB
01-81.txt AC 81 ms 5376 KB
01-82.txt AC 85 ms 5376 KB
01-83.txt AC 93 ms 5376 KB
01-84.txt AC 100 ms 5376 KB
01-85.txt AC 94 ms 5376 KB
01-86.txt AC 103 ms 5376 KB
01-87.txt AC 102 ms 5376 KB
01-88.txt AC 105 ms 5376 KB
01-89.txt AC 101 ms 5376 KB
01-90.txt AC 39 ms 5376 KB
01-91.txt AC 78 ms 5376 KB
01-92.txt AC 92 ms 5376 KB
01-93.txt AC 90 ms 5376 KB
01-94.txt AC 83 ms 5376 KB
01-95.txt AC 86 ms 5376 KB
01-96.txt AC 38 ms 5376 KB
01-97.txt AC 75 ms 5376 KB
01-98.txt AC 84 ms 5376 KB
sample-01.txt AC 3 ms 256 KB
sample-02.txt AC 3 ms 256 KB