一道模拟题目
对于所有0 还是 1 我们都可以想象做均为 0 的状态
v[i]表示原来的值
但是对于原来为1的要加上其所在的值作为初始值
然后转化后 a[i] = -v[i] , 如果原来为0 , 那就直接赋值
我们总是希望将尽可能大的值先加 ,所以将a由大到小排个序 , 一直加到负数的时候需要考虑这个负数取不取,其实我们最多取一个负数,因为当加了
第一个负数若后面还为负数,那么我们可以将那个负数倒转又加回来即可
但第一个负数取不取也要看它的绝对值是不是比前一个数大,如果大,说明宁可将前一个数再变一次颜色后舍去也不需要加后一个负数
最后我们就确定实际上使用的数了,如果操作数大于这个数,说明超过范围只是不断的将最小的数不断改变颜色
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int N = 100005; 6 int col[N] , v[N] , a[N]; 7 8 bool cmp(int a , int b) 9 { 10 return a>b; 11 } 12 13 int main() 14 { 15 // freopen("a.in" , "r" , stdin); 16 int n , m; 17 while(scanf("%d%d" , &n , &m) == 2) 18 { 19 for(int i = 0 ; i<n ; i++) 20 scanf("%d" , col+i); 21 for(int i = 0 ; i<n ; i++) 22 scanf("%d" , v+i); 23 24 int val = 0; 25 for(int i=0 ; i<n ; i++) 26 if(col[i]){ 27 val += v[i]; 28 a[i] = -v[i]; 29 } 30 else{ 31 a[i] = v[i]; 32 } 33 sort(a , a+n , cmp); 34 for(int i = 0 ; i<n ; i++){ 35 if(a[i] < 0){ 36 if(i == 0){ 37 n = 1; 38 break; 39 } 40 if(-a[i] > a[i-1]) n = i; 41 else n = i+1; 42 break; 43 } 44 } 45 if(m<=n){ 46 for(int i = 0 ; i<m ; i++) 47 val += a[i]; 48 } 49 else{ 50 for(int i = 0 ; i<n ; i++){ 51 val += a[i]; 52 } 53 if((m-n)&1) val -= a[n-1]; 54 } 55 printf("%d " , val); 56 } 57 return 0; 58 }