CodeForces730E Award Ceremony(拓扑排序+结论)
CF730E. Award Ceremony
- problem
- solution
- code
problem
題目鏈接
題目大意:
給出 nnn 個隊封榜時的榜單 aia_iai? 和揭榜時的變化情況 did_idi?。
揭榜時,這個隊的名次會變化 tit_iti?。
注意在別的隊揭榜時,自己隊的排名也是動態(tài)變化的。
計算的變化名次是自己揭榜前后的名次差,而非最終排名與最初排名差。
然后問如何安排揭榜順序,使得 sum(∣ti∣)sum(|t_i|)sum(∣ti?∣) 最大。
1≤n≤100,1≤ai≤100,?100≤di≤1001≤n≤100,1≤ai≤100, -100≤di≤1001≤n≤100,1≤ai≤100,?100≤di≤100。
solution
考慮兩兩隊伍之間的排名變化貢獻。
-
如果兩個隊伍揭榜前后相對排名順序發(fā)生變化,則無論怎么安排兩個隊伍的揭榜先后,答案貢獻都是 111。
i.e. 假設(shè) iii 排名在 jjj 前面(i<ji<ji<j),揭榜后 jjj 排名更靠前 i>ji>ji>j。
有兩種情況。
- iii 分?jǐn)?shù)下降,jjj 可能上升也可能下降,但 iii 一定下降地更猛。
- 假設(shè)先揭榜 iii ,則 iii 排名變成 jjj 后面,貢獻為 111,后面揭榜 jjj,依舊在 iii 之前。
- 假設(shè)先揭榜 jjj,則 jjj 可能已經(jīng)超過 iii ,后面揭榜仍在 iii 前面;也可能還是沒有超過 iii,但是 iii 揭榜后就掉在 jjj 后面了。
- iii 分?jǐn)?shù)上升,jjj 必須上升,且 jjj 一定上升地更猛。假設(shè)揭榜過程與上面一樣。不再贅述。
- iii 分?jǐn)?shù)下降,jjj 可能上升也可能下降,但 iii 一定下降地更猛。
-
如果兩個隊伍揭榜前后相對順序并未發(fā)生改變。則有兩種情況。
- 不管先揭榜誰,都保持著 i<ji<ji<j。則對答案無貢獻。
- iii 被 jjj 超過后又再次超過了 jjj。答案就是 222。
按照上述方法會得到一個有向無環(huán)圖,根據(jù)拓?fù)渑判蚓湍艿玫浇視缘捻樞?#xff0c;但是本題并未做要求。
只要最終改變的最大值結(jié)果,那么就直接枚舉兩個隊伍,看屬于上面的哪種情況貢獻。計算即可。
時間復(fù)雜度為 O(n2)O(n^2)O(n2)。
證明這樣的做法得到的關(guān)系圖不存在環(huán)。
只有第二種情況的第二點,貢獻為 222,這種 case 會需要考慮兩個隊伍揭榜的先后順序。
即只有這種 case 才會在圖上增加一條邊,因此環(huán)只可能在這個地方產(chǎn)生。
假設(shè)三個隊伍 i,j,ki,j,ki,j,k 構(gòu)成環(huán)。
首先因為兩個隊伍之間有邊,所以有 iii 揭榜后能超過 jjj ,然后又被 jjj 揭榜后反超,這樣貢獻才為 222。
(j,k),(k,i)(j,k),(k,i)(j,k),(k,i) 同樣也是如此。
即 jjj 揭榜后超過 kkk 又被 kkk 反超,kkk 揭榜后超過 iii 又被 iii 反超。
這三個揭榜順序必然是確定的,所以名次改變方向是固定的。
由 (i,j)(j,k)(i,j)(j,k)(i,j)(j,k) 之間的關(guān)系就知道 kkk 揭榜后超過 i,ji,ji,j 不可能又讓 iii 再揭榜一次反超。
所以這個情況必然是如圖所示:
code
#include <bits/stdc++.h> using namespace std; #define maxn 105 struct node { int val, id, tag;bool operator < ( node &t ) {return val == t.val ? id < t.id : val > t.val;} }a[maxn]; int n, ans;int calc( int x, int y ) {node lst_x = a[x], lst_y = a[y];node new_x = lst_x, new_y = lst_y;new_x.val += lst_x.tag;new_y.val += lst_y.tag;if( lst_x < lst_y and new_y < new_x ) return 1;if( lst_y < lst_x and new_x < new_y ) return 1;if( lst_x < lst_y and new_x < new_y and new_y < lst_x ) return 2;if( lst_x < lst_y and new_x < new_y and lst_y < new_x ) return 2;if( lst_y < lst_x and new_y < new_x and new_x < lst_y ) return 2;if( lst_y < lst_x and new_y < new_x and lst_x < new_y ) return 2;return 0; }int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) scanf( "%d %d", &a[i].val, &a[i].tag ), a[i].id = i;sort( a + 1, a + n + 1 );for( int i = 1;i <= n;i ++ )for( int j = i + 1;j <= n;j ++ )ans += calc( i, j );printf( "%d\n", ans );return 0; }總結(jié)
以上是生活随笔為你收集整理的CodeForces730E Award Ceremony(拓扑排序+结论)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 平鱼的家常做法 平鱼如何做
- 下一篇: 帝国程序怎么重置id(帝国单机重置)