1. 程式人生 > >2016.10.06【初中部 NOIP提高組 】模擬賽C

2016.10.06【初中部 NOIP提高組 】模擬賽C

寫在前面:這一套比賽聽說是一位OI界的神犇出的題,果然質量很高啊,要好好總結。

T1:

It very simple.

You can 排序,and 模擬 and AC.

T2:

一眼知道是DP.

關鍵沒想到怎麼去無後效性.

很明顯只需要倒著推,因為當你在倒著推做到第i個的時候,i+1~n都是沒有變過的,所以並不會對i產生影響,也就是去除了無後效性.

明白了去無後效性後,想想狀態怎麼設定.

對於第i段路的高度,要麼它就不與前面的交換,要麼就交換.

則很明顯可以設

f[i,0]表示第i段路不換的最優值.

f[i,1]表示第i段路換的最優值.

希望狀態轉移方程各位能自己推推,不難.

{

轉移如下:

如何計算f[i,0]呢?

很明顯,至於f[i+1,0/1]有關.

f[i,0]=min{f[i+1,0]+abs(a[i]-a[i+1]),f[i+1,1]+abs(a[i]-a[i+2])}

為什麼這樣呢?

因為如果第i+1個不交換,那麼第i個就要走到第j個,花費為abs(a[i]-A[I+1])

而如果第i+1個交換了,則不管它怎麼換,換到哪裡,花費都是abs(a[i]-a[i+2]),因為i+2會移到i+1這個位置。

然而f[i,0]應該是最好求的,那麼f[i,1]怎麼求呢?

因為我們不知道第i個位置它要移到哪去,所以,我們可以列舉.

設第i個數移到j這個位置


i移到j這個位置,則i+1~j的所有位置都往前移了一個格,i會與j產生一個新的差

記為x1=abs(a[i]-a[j])

而i+1~j他們之前互相會產生一個差,我們要求這些差的和,很明顯用字首和可以求,記為x2=Sj-S(i+1)

那麼x1和x2是不變數,而對於第j+1位,如果它不換,則答案=f[j+1,0]+x1+x2+abs(a[i]-a[j+1])

如果換了,則答案=f[j+1,1]+x1+x2+abs(a[i]-a[j+2]),很明顯答案取兩者較優,至於為什麼,則與求f[i,0]的思路是類似的,自行思考.

}

T3:

考試時打的暴力,但正解非常巧妙.

可以把一個矩陣裡的相同型別數字看做一些點,那麼這些點之間互隔的距離會產生一些類似矩陣,把這些矩陣的大小累加即為答案.

f[i,0]表示第i個數當前最靠左的位置.

f[i,1]表示第i個數當前次靠左的位置.

很明顯,第一次遇到i這個數,我們需要累加答案,是(m-j+1)*(n-i+1){i表示行,j表示列},並記錄f[i,0],以及把f[i,1]的值賦值為M+1,方便第二次遇到i時計算.

而第二次遇到i時,

假設是在f[i,1]的左邊,則需要減去答案 (f[i,1]-j)*(n-i+1),並記錄f[i,1].

假設是在f[i,0]的左邊,那就f[i,0]與f[i,1]一起更新,並累加答案(f[i,0]-j)*(n-i+1),再減去答案(f[i,1]-f[i,0])*(n-i+1).

以此類推……

這樣子,則可以求出答案,這需要自己去意會,理解一下,就不多說了。

T4:

一道很巧的規律題:

當前加入的第i個數,b[i]只有可能與b[i-1]的差在0~2之間,why?

Because——

前i-1個數,因為要求互不相等,所以如果前i-1個數當中有一個i-1的且第i個增加的數<=i則 b[i]=b[i-1]+2

如果前i-1個數當中有一個i-1但第i個數>i,則 b[i]=b[i-1]+1

當=0的時候,很明顯對答案是沒貢獻的.

接下來分類討論:

當b[i]=b[i-1]+2的時候,

前面i-1個數本來能放i-1個<=i的數,但因為前面有b[i-1]個<=i-1的數,所以前i-1個數能放的<=i的個數為i-1-b[i-1]

而第i個位置本來能放i個<=i的數,但與之前的原因一樣,只能放i-b[i-1]個,但又由於前i-1個數又多放了一個<=i的數,所以第i個位置只能放的個數需要再減1.當b[i]=b[i-1]+1的時候,

第i個數能放i-b[i-1]個<=i的數,前i-1個位置能放i-1-b[i-1]的數,方案數是累加的,因為一次只能放一個.

規律如下:

當b[i]-b[i-1]=1:i-b[i-1]-1+i-b[i-1]

當b[i]-b[i-1]=2:(i-b[i]-1)*(i-b[i]-1)

最後高精度即可.