今天又是例行考试的说。
话说我今天loj大凶且忌参加模拟赛,洛谷也好不到哪去,怕不是要爆零了QAQ。
T1:卡片游戏:
这题看到数据范围1e5,铁定不是费用流了。
这种东西显然不可能是dp,看看怎么贪心?
首先,我们如果给一张卡片负号,则一定去较大的那个值,正号则取较小的那个。
两边的差值是大小两值的和。
所以,我们先贪心地给负号,并把卡片放进一个堆里,如果堆已满且堆顶的数值和小于当前卡片的数值和,那么我们弹出堆顶,放入当前卡片。
考虑一正一负且负数的绝对值大的情况,也能通过。
写了拍了没啥问题,就这样了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 #define debug cout 7 using namespace std; 8 const int maxn=1e5+1e2; 9 10 struct Node { 11 int mx,mi; 12 friend bool operator < (const Node &a,const Node &b) { 13 return a.mx + a.mi < b.mx + b.mi; 14 } 15 }ns[maxn]; 16 17 multiset<Node> heap; 18 19 int main() { 20 static int n,lim,ans; 21 scanf("%d",&n) , lim = n >> 1; 22 for(int i=1;i<=n;i++) { 23 scanf("%d%d",&ns[i].mx,&ns[i].mi); 24 if( ns[i].mx < ns[i].mi ) 25 swap(ns[i].mx,ns[i].mi); 26 } 27 for(int i=1;i<=n;i++) { 28 if( heap.size() < lim ) { 29 heap.insert(ns[i]); 30 ans -= ns[i].mx; 31 } else if( *heap.begin() < ns[i] ) { 32 Node b = *heap.begin(); 33 heap.erase(heap.begin()); 34 ans += b.mx , ans += b.mi; 35 heap.insert(ns[i]); 36 ans -= ns[i].mx; 37 } else ans += ns[i].mi; 38 } 39 40 printf("%d\n",ans); 41 42 return 0; 43 }