1. 程式人生 > >【BZOJ1432】函式(ZJOI2009)-思維

【BZOJ1432】函式(ZJOI2009)-思維

測試地址:函式
做法: 本題需要用到思維。
如果在 x x 座標為負無窮時,把函式從下到上編號為 1 1 ~ n

n ,那麼在向右掃時,一旦遇到一個交點,就表示交的這兩個函式上下位置進行交換。因為每兩個函式間有且僅有一個交點,且不會有三個函式共點,因此這些交換是先後進行的,且一定是發生在下面的函式編號比上面的函式小時,那麼最後在 x x 座標為正無窮時必定會換為從下到上 n
n
~ 1 1 的形式。於是現在要求第 k k 層的段數,實際上就是在交換的過程中,從下到上第 k
k
個位置上編號的最小變動次數 + 1 +1
根據推理,一個位置上編號最小的變動次數為 min ( 2 k 1 , 2 ( n k + 1 ) 1 ) \min(2k-1,2(n-k+1)-1) 。首先這兩種情況是對稱的,因此我們只考慮 k ( n k + 1 ) k\le (n-k+1) 的情況,我們肯定考慮把右邊最大的 k k 個數挪到左邊去,那麼最小的交換次數就是,前 k 1 k-1 個數因為要經過那個位置,所以都產生 2 2 的貢獻,而最後一個數正好放在那個位置上,因此只產生 1 1 的貢獻,總貢獻就是 2 k 1 2k-1 了,那麼另一種情況只要對稱考慮即可。因此答案為 min ( 2 k , 2 ( n k + 1 ) ) \min(2k,2(n-k+1)) n = k = 1 n=k=1 時需要特判,這樣我們就非常簡單地解決了這一題。
以下是本人程式碼:

#include <bits/stdc++.h>
using namespace std;
int n,k;

int main()
{
	scanf("%d%d",&n,&k);
	if (n==1) printf("1");
	else printf("%d",min(2*k,2*(n-k+1)));
	
	return 0;
}