常用的网站开发平台api,咸阳做网站的公司电话,天津住建网官网,杭州软件开发培训学校CF730E. Award Ceremonyproblemsolutioncodeproblem
题目链接
题目大意#xff1a;
给出 nnn 个队封榜时的榜单 aia_iai 和揭榜时的变化情况 did_idi。
揭榜时#xff0c;这个队的名次会变化 tit_iti。
注意在别的队揭榜时#xff0c;自己队的排名也是动态变化的…
CF730E. Award Ceremonyproblemsolutioncodeproblem
题目链接
题目大意
给出 nnn 个队封榜时的榜单 aia_iai 和揭榜时的变化情况 did_idi。
揭榜时这个队的名次会变化 tit_iti。
注意在别的队揭榜时自己队的排名也是动态变化的。
计算的变化名次是自己揭榜前后的名次差而非最终排名与最初排名差。
然后问如何安排揭榜顺序使得 sum(∣ti∣)sum(|t_i|)sum(∣ti∣) 最大。
1≤n≤1001≤ai≤100,−100≤di≤1001≤n≤1001≤ai≤100, -100≤di≤1001≤n≤1001≤ai≤100,−100≤di≤100。
solution
考虑两两队伍之间的排名变化贡献。 如果两个队伍揭榜前后相对排名顺序发生变化则无论怎么安排两个队伍的揭榜先后答案贡献都是 111。 i.e. 假设 iii 排名在 jjj 前面ijijij揭榜后 jjj 排名更靠前 ijijij。 有两种情况。 iii 分数下降jjj 可能上升也可能下降但 iii 一定下降地更猛。 假设先揭榜 iii 则 iii 排名变成 jjj 后面贡献为 111后面揭榜 jjj依旧在 iii 之前。假设先揭榜 jjj则 jjj 可能已经超过 iii 后面揭榜仍在 iii 前面也可能还是没有超过 iii但是 iii 揭榜后就掉在 jjj 后面了。 iii 分数上升jjj 必须上升且 jjj 一定上升地更猛。假设揭榜过程与上面一样。不再赘述。 如果两个队伍揭榜前后相对顺序并未发生改变。则有两种情况。 不管先揭榜谁都保持着 ijijij。则对答案无贡献。iii 被 jjj 超过后又再次超过了 jjj。答案就是 222。
按照上述方法会得到一个有向无环图根据拓扑排序就能得到揭晓的顺序但是本题并未做要求。
只要最终改变的最大值结果那么就直接枚举两个队伍看属于上面的哪种情况贡献。计算即可。
时间复杂度为 O(n2)O(n^2)O(n2)。 证明这样的做法得到的关系图不存在环。 只有第二种情况的第二点贡献为 222这种 case 会需要考虑两个队伍揭榜的先后顺序。 即只有这种 case 才会在图上增加一条边因此环只可能在这个地方产生。 假设三个队伍 i,j,ki,j,ki,j,k 构成环。 首先因为两个队伍之间有边所以有 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) 之间的关系就知道 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;
}