一道模拟题目

对于所有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\n" , val);
56     }
57     return 0;
58 }

 

 posted on 2015-01-17 22:56  Love风吟  阅读(169)  评论(0编辑  收藏  举报