1. 程式人生 > 其它 >CF1493A Anti-knapsack 題解

CF1493A Anti-knapsack 題解

CF1493A Anti-knapsack 題解

Content

給定 \(T\) 組資料,每組資料給定兩個數 \(n\)\(k\),要你從 \(1\sim n\) 中選出最多的數,使得這些數中不存在某些數的和為 \(k\),並輸出方案。

資料範圍:\(1\leqslant T\leqslant 100\)\(1\leqslant k\leqslant n\leqslant 1000\)

Solution

很容易想到,如果 \(k<n\),那麼 \([k+1,n]\) 之間的所有整數都是可以取的,因此我們先選完所有在 \([k+1,n]\) 之間的整數。

顯然 \(k\) 是不能夠取的。因此我們現在再考慮 \([1,k-1]\) 之間的情況,其實也很簡單。我們開一個 \(vis\)

陣列(\(vis_i\) 表示數 \(i\) 是否取過,取過為 \(1\),沒取過為 \(0\)),然後在取當前數 \(i\) 的時候,看是否有 \(vis_{k-i}=1\),如果 \(vis_{k-i}=1\),那麼 \(i\) 就不能再去取了,否則你就可以取這個數。

至於方案直接再開個陣列統計就好了,具體看程式碼實現。

Code

int ans[1007], vis[1007];

int main() {
	MT {
		memset(ans, 0, sizeof(ans));
		memset(vis, 0, sizeof(vis));
		int n = Rint, k = Rint;
		R(i, n, k + 1) ans[++ans[0]] = i;
		R(i, k - 1, 1) if(!vis[k - i]) ans[++ans[0]] = i, vis[i] = 1;
		write(ans[0]), puts("");
		F(i, 1, ans[0]) write(ans[i]), putchar(' ');
		puts("");
	} 
	return 0;
}