2018年第九届蓝桥杯 第十题:乘积最大(满分25分)

标题:乘积最大
给定N个整数A1, A2, ... AN。请你从中选出K个数,使其乘积最大。 
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数。 
注意,如果X<0, 我们定义X除以1000000009的余数是负(-X)除以1000000009的余数。
即:0-((0-x) % 1000000009)
【输入格式】
第一行包含两个整数N和K。 
以下N行每行一个整数Ai。 
对于40%的数据,1 <= K <= N <= 100 
对于60%的数据,1 <= K <= 1000 
对于100%的数据,1 <= K <= N <= 100000  -100000 <= Ai <= 100000 
【输出格式】
一个整数,表示答案。

【输入样例】
5 3
-100000  
-10000  
2  
100000 
10000 
【输出样例】
999100009
再例如:
【输入样例】
5 3
-100000  
-100000  
-2  
-100000 
-100000
【输出样例】
-999999829

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms
 
 
 
  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4 
  5 const long long  M  = 1000000009;
  6 
  7 class Num{
  8 public:
  9     long long a; // 商数
 10     long long b; // 余数 
 11     Num(long long x = 0){
 12         a = x/M;
 13         b = x%M;
 14     }
 15     Num(long long a,long long b){
 16         this->a = a;
 17         this->b = b;
 18     }
 19     Num operator *(Num &num){    
 20         long long a1 = a*num.a*M + a*num.b + b*num.a + b*num.b/M;
 21         long long b1 = b*num.b%M;
 22         Num temp(a1,b1);
 23         return temp;
 24     } 
 25     void operator = (Num x){
 26         a = x.a;
 27         b = x.b;
 28     }
 29     bool operator > (Num num){
 30         if(a>num.a)
 31             return true;
 32         else if(a<num.a)
 33             return false;
 34         else 
 35             return b>num.b;    
 36     }
 37 };
 38 
 39 const long N = 100000;
 40 const long K = 100000;
 41 Num * *  v_max; 
 42 Num * *  v_min;
 43 typedef Num * NumPtr; 
 44 long long a_input[N+1];
 45 
 46 void init_a(int n){
 47     v_max = new NumPtr[n+1];
 48     v_min = new NumPtr[n+1];
 49     for(int i=1;i<=n;i++){
 50         v_max[i] = new Num[i+1];
 51         v_min[i] = new Num[i+1];
 52     }
 53     long long _max = a_input[1];
 54     long long _min = a_input[1];
 55     for(int i=1; i<=n; i++){
 56         if (a_input[i]>_max){
 57             _max = a_input[i];
 58         }
 59         v_max[i][1] = _max;
 60         if (a_input[i]< _min){
 61             _min = a_input[i];
 62         }
 63         v_min[i][1] = _min;
 64     }
 65     Num _ii = 1;
 66     for(int i=1;i<=n;i++){
 67         Num a_i = a_input[i];
 68         _ii = _ii*a_i;
 69         v_max[i][i] = _ii;
 70         v_min[i][i] = _ii;
 71     }    
 72 }
 73 
 74 void fill_a(int n){
 75     for(int i=3;i<=n;i++){
 76         for(int j=2;j<i;j++){
 77             // fill v_max and fill v_min
 78             Num n1_max = v_max[i-1][j];
 79             Num n2_max = 0;
 80             Num n1_min = v_min[i-1][j];
 81             Num n2_min = 0;
 82             Num  a_i = a_input[i];
 83             if(a_input[i]>0){                
 84                 n2_max = a_i*v_max[i-1][j-1];
 85                 n2_min = a_i*v_min[i-1][j-1]; 
 86             }else if(a_input[i]<0){
 87                 n2_max = a_i*v_min[i-1][j-1];
 88                 n2_min = a_i*v_max[i-1][j-1];
 89             }
 90             if (n1_max>n2_max){
 91                 v_max[i][j] = n1_max;
 92             }else{
 93                 v_max[i][j] = n2_max;
 94             }
 95             if (n1_min>n2_min){
 96                 v_min[i][j] = n2_min;
 97             }else{
 98                 v_min[i][j] = n1_min;
 99             }            
100         }
101     }
102 }
103 
104 int main()
105 {
106     int n,k;
107     cin>>n>>k;
108     for(int i=1;i<=n;i++){
109         cin>>a_input[i];
110     }    
111     init_a(n);
112     fill_a(n);
113     cout<<v_max[n][k].b<<endl;
114     return 0;            
115 }
116 
117  
View Code

 

  1 const long long  M  = 1000000009;
  2 #include <iostream>
  3 #include <vector>
  4 using namespace std;
  5 class Num{
  6 public:
  7     long long a; // 商数
  8     long long b; // 余数 
  9     Num(long long x = 0){
 10         a = x/M;
 11         b = x%M;
 12     }
 13     Num(long long a,long long b){
 14         this->a = a;
 15         this->b = b;
 16     }
 17     Num operator *(Num &num){    
 18         long long a1 = a*num.a*M + a*num.b + b*num.a + b*num.b/M;
 19         long long b1 = b*num.b%M;
 20         Num temp(a1,b1);
 21         return temp;
 22     } 
 23 //    void operator = (long long x){
 24 //        a = x/M;
 25 //        b = x%M;
 26 //    }
 27     void operator = (Num x){
 28         a = x.a;
 29         b = x.b;
 30     }
 31     bool operator > (Num num){
 32         if(a>num.a)
 33             return true;
 34         else if(a<num.a)
 35             return false;
 36         else 
 37             return b>num.b;    
 38     }
 39     bool operator < (Num num){
 40         if(a<num.a)
 41             return true;
 42         else if(a>num.a)
 43             return false;
 44         else 
 45             return b<num.b;    
 46     }
 47 
 48 //    bool operator == (Num &num){
 49 //        return (a==num.a) && (b==num.b);
 50 //    }
 51     
 52 };
 53 ostream & operator << (ostream & os, Num &num){
 54     os<<"("<<num.a<<","<<num.b<<")";
 55 }
 56 //const Num ZERO(0);
 57 const long N = 100000;
 58 const long K = 100000;
 59 //Num a_max[N+1][K+1];
 60 //Num a_min[N+1][K+1];
 61 vector< vector<Num> >  v_max(N+1); 
 62 vector< vector<Num> >  v_min(N+1);
 63 typedef Num * NumPtr; 
 64 long long a_input[N+1];
 65 void init_a(int n){
 66     for(int i=1;i<=n;i++){
 67         v_max[i].resize(i+1);
 68         v_min[i].resize(i+1);
 69     }
 70     long long _max = a_input[1];
 71     long long _min = a_input[1];
 72     for(int i=1; i<=n; i++){
 73         if (a_input[i]>_max){
 74             _max = a_input[i];
 75         }
 76         v_max[i][1] = _max;
 77         if (a_input[i]< _min){
 78             _min = a_input[i];
 79         }
 80         v_min[i][1] = _min;
 81     }
 82     Num _ii = 1;
 83     for(int i=1;i<=n;i++){
 84         Num a_i = a_input[i];
 85         _ii = _ii*a_i;
 86         v_max[i][i] = _ii;
 87         v_min[i][i] = _ii;
 88     }    
 89 }
 90 void fill_a(int n){
 91     for(int i=3;i<=n;i++){
 92         for(int j=2;j<i;j++){
 93             // fill v_max and fill v_min
 94             Num n1_max = v_max[i-1][j];
 95             Num n2_max = 0;
 96             Num n1_min = v_min[i-1][j];
 97             Num n2_min = 0;
 98             Num  a_i = a_input[i];
 99             if(a_input[i]>0){                
100                 n2_max = a_i*v_max[i-1][j-1];
101                 n2_min = a_i*v_min[i-1][j-1]; 
102             }else if(a_input[i]<0){
103                 n2_max = a_i*v_min[i-1][j-1];
104                 n2_min = a_i*v_max[i-1][j-1];
105             }
106             if (n1_max>n2_max){
107                 v_max[i][j] = n1_max;
108             }else{
109                 v_max[i][j] = n2_max;
110             }
111 //            if (n1_min>n2_min){
112 //                v_min[i][j] = n2_min;
113 //            }else{
114 //                v_min[i][j] = n1_min;
115 //            }
116             
117             if (n1_min<n2_min){
118                 v_min[i][j] = n1_min;
119             }else{
120                 v_min[i][j] = n2_min;
121             }
122                         
123         }
124     }
125 }
126 void print_a(int n){
127     for(int i=1;i<=n;i++){
128         for(int j=1;j<=i;j++){
129             cout<<v_max[i][j]<<" | ";
130         }
131         cout<<endl;
132     }
133 }
134 void print_a_min(int n){
135     for(int i=1;i<=n;i++){
136         for(int j=1;j<=i;j++){
137             cout<<v_min[i][j]<<" | ";
138         }
139         cout<<endl;
140     }
141 }
142 int main()
143 {
144     int n,k;
145     cin>>n>>k;
146     for(int i=1;i<=n;i++){
147         cin>>a_input[i];
148     }    
149     init_a(n);
150     fill_a(n);
151     //print_a(n);
152     //cout<<"-------------------"<<endl;
153     //print_a_min(n);
154     cout<<v_max[n][k].b<<endl;
155     return 0;            
156 }
157 
158     /* 自动计算的余数已经可以满足规则 
159     if (v_max[n][k].a > 0)
160         cout<<(v_max[n][k]).b<<endl;
161     else if (v_max[n][k].a < 0){
162         cout<<-((-v_max[n][k].b)%M)<<endl;
163     }else if (v_max[n][k].a==0){
164         if (v_max[n][k].b>=0){
165             cout<<(v_max[n][k]).b<<endl;
166         }else{
167             cout<<-((-v_max[n][k].b)%M)<<endl;
168         }
169     }
170     */
View Code

 

转载于:https://www.cnblogs.com/candyYang/p/10508791.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值