Loading

【题解】ARC128E-K Different Values

难度不低的思维题。

首先我们不难想出一个构造可行解的方法。

首先我们对序列分块。令总长度 \(M=\sum A_i\),将长度为 \(M\) 的序列分成长度为 \(K\) 的块,最后一块长度 \(\le K\)​。

显然如果有解,则 \(A_i\le cnt\)\(\sum [A_i = cnt] \le res\),并且这是充要条件。其中 \(cnt\) 表示块数,\(res\) 表示最后一块长度。

接下来构造可行解,我们先将 \(A_i = cnt\) 的数填到每一块的最前面。对于 \(A_i < cnt\) 的数,我们按 \(A_i\) 从大到小排序,然后依次考虑每个数。记录一个指针,初始为第一个空位,每填一个数向后移动 \(K\) 格,如果后面没有位置则回到第一个空位。不难发现这样构造下去一定有解。

但是这样构造和最优化没有任何关系。鉴于笔者水平很菜,下面是对官方题解的翻译和理解。

上面的推导得到有解的充要条件,由于是字典序最小,比较套路的做法是枚举当前位填什么,再看后面位置是否可行。

所以如果 \(\sum [A_i = cnt] = res\) 则当前位必须填 \(A_i = cnt\) 的数,其他情况则没有限制。所以每次选择在这个限制下,在前面 \(K-1\) 个位置没有出现的数中最小的并填上,得到一个规模为 \(M-1\) 的子问题,归纳下去即可。

这个方法看上去就非常离谱,但下面考虑证明这个方法的正确性。

这等价于证明如果最初序列有解,则按照这个构造方法,任意时刻都至少有一个数可以选择。

反证法,假设存在一个时刻没有别的选择了。分以下两种情况讨论

  • \(1.\) 如果 \(\sum [A_i=cnt] = res\),那么对于前面 \(K-1\) 个数,所有这 \(res\) 个数都出现了一次。那么加上前面这 \(K-1\) 个数,此时存在 \(res\) 个数 \(A_i = cnt\)。但是加上 \(K-1\) 个数后重新进行分块,不难发现此时的 \(res' = res-1\)。所以此时 \(\sum [A_i = cnt] > res'\),矛盾。
  • \(2.\) 如果 \(\sum[A_i=cnt] < res\),那么 \(A_i > 0\) 的数都可以选,所以 \(A_i > 0\) 的数 \(\le K-1\)。假设包括当前位置后面还有 \(S\) 个空位,如果 \(S \ge K\),而相邻 \(K\) 个位置不相同,则存在 \(\ge K\)\(A_i >0\) 的数,所以 \(S\le K - 1\)。既然 \(S\le K - 1\)​,显然只能分成 \(1\) 块,此时所有 $A_i $ 都等于 \(cnt\),因此 \(\sum [A_i = cnt] = res\),矛盾。

所以按照给定的构造方法,一定能构造出最优解,时间复杂度 \(\mathcal{O}(N\sum A_i)\)

#define N 505
int n, k, a[N], lst[N];
inline int g(int x){
	if(x % k == 0)return k;
	return x % k;
}
int main() {
	//int T = read();while(T--)solve();
	n = read(), k = read();
	int sum = 0, m = 0;
	rp(i, n)m += a[i] = read(), lst[i] = -k;
	rp(i, n){
		if(a[i] > (m - 1) / k + 1){puts("-1");return 0;}
		sum += a[i] == (m - 1) / k + 1;
	}
	if(sum > g(m)){puts("-1");return 0;}
	rp(i, m){
		sum = 0;
		rp(j, n)sum += a[j] == (m - i) / k + 1;
		if(sum == g(m - i + 1)){
			rp(j, n)if(a[j] == (m - i) / k + 1 && lst[j] + k <= i){
				printf("%d ", j), a[j]--, lst[j] = i; break;
			}
		}
		else{
			rp(j, n)if(a[j] && lst[j] + k <= i){
				printf("%d ", j), a[j]--, lst[j] = i; break;
			}
		}
	}
	return 0;
}
posted @ 2021-11-10 22:48  7KByte  阅读(108)  评论(0编辑  收藏  举报