zoukankan      html  css  js  c++  java
  • Chemistry

    Problem A. Chemistry

    Input file: chemistry.in

    Output file: chemistry.out

    Time limit: 1 seconds

    Memory limit: 256 megabytes

    香香手中有n瓶化学药剂,每瓶化学药剂都有一个能量值ai。现在她想把这些药剂的能量值全部变成一样的,她有两台机器,其中一台机器一次可以把一瓶药剂的能量值翻倍,ai变成2ai,另一台机器一次可以把一瓶药剂的能量值变为一半,ai变成

    然而每台每次启动都需要单位1的能量,她所储存的能量不多了,请你帮她计算一下用最少的能量完成这个任务。

    Input

    第一行输入一个n(1 <= n <= 10^5 )

    第二行输入n个数,用空格隔开,表示每瓶药剂的能量值ai

    (1 <= ai <= 10^5)

    Output

    输出一行,表示最少需要的能量值是多少。

    Sample test(s)

    input

    3
    4 8 2

    output

    2

    input

    3
    3 5 6

    output

    5

    样例解释:

    第一个样例能量值全部为成4 ,第二个样例全部变为1

    范围:

    对于10% , n = 2

    对于30% , n <= 100

    对于另10% , ai <= 1000

    对于100% , n <= 10^5 , ai <= 10^5

     

      分析:

      明显的DP,f[i][j]表示前i个数全部变成j所要耗费的能量,然后就是各种优化。。。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cmath>
      7 using namespace std;
      8 const int MAX=100005;
      9 const int inf=0x3f3f3f3f;
     10 int a[MAX];
     11 int b[MAX],b2[MAX];
     12 int c[10000000];
     13 int f[10][1000000];
     14 int may[1000000];
     15 int N;
     16 int ANS=inf;
     17 int MIN;
     18 int main(){
     19 //    freopen("chemistry.in","r",stdin);
     20 //    freopen("chemistry.out","w",stdout);
     21     scanf("%d",&N);
     22     for(int i=1;i<=N;i++) scanf("%d",&a[i]);
     23     sort(a+1,a+N+1);
     24     for(int i=1;i<=N;i++) b[i]=a[i],b2[i]=a[i];
     25     
     26     for(int i=1;i<=N;i++){//筛出来可能存在的数字 
     27         may[b[i]]++;
     28         
     29         while(b[i]*2<=4*a[N]){
     30             may[b[i]*2]++;
     31             b[i]*=2;
     32         }
     33         while(b2[i]/2>=1){
     34             may[b2[i]/2]++;
     35             b2[i]/=2;
     36         }
     37         
     38     }
     39     
     40     int now=0;
     41     for(int i=1;i<=4*a[N];i++){
     42         if(may[i]==N){//不为偶数的 
     43             now++;
     44             c[now]=i;    
     45         }
     46     }
     47     
     48     for(int k=1;k<=4*a[N]; ){
     49         if(may[k]!=N){
     50             now++;
     51             c[now]=k;
     52         }
     53         k<<=1;
     54     }
     55     //f[i][j]表示前i个数,全部变成c[j]时,所需的能量 
     56 
     57     for(int j=1;j<=now;j++){
     58         for(int i=1;i<=N;i++){//DP
     59             int num=c[j];
     60             int ans=0;
     61             
     62             if(may[num]==N){//序列中的每个数都可以直升直降得到 
     63             
     64                 if(num==a[i]) ans=0;
     65                 if(num>a[i]){
     66                     int x=a[i];
     67                     while(x!=num){
     68                         x*=2;
     69                         ans++;
     70                     }
     71                 }
     72                 if(num<a[i]){
     73                     int x=a[i];
     74                     while(x!=num){
     75                         x/=2;
     76                         ans++;
     77                     }
     78                 }
     79             }
     80             //*********
     81             else{//有的数字必须先降再升可以达到 
     82                 int x=a[i];
     83                 if(num==a[i]) ans=0;
     84                 if(num>a[i]){
     85                     while(x!=num){
     86                         x<<=1;
     87                         ans++;
     88                         if(x>num){
     89                             ans=inf;
     90                             break;
     91                         }
     92                     }
     93                 }
     94                 if(ans==0&&num!=a[i]) 
     95                     ans=inf;
     96                 if(x!=num){
     97                     int ans1=0;
     98                     int x=a[i];
     99                     while(x!=1){
    100                         if(x==num) break;
    101                         else{
    102                             x>>=1;
    103                             ans1++;
    104                         }
    105                     }
    106                     while(x!=num){
    107                         x<<=1;
    108                         ans1++;
    109                     }
    110                     ans=min(ans,ans1);
    111                 }    
    112             }
    113             f[2][j]=f[1][j]+ans;
    114             f[1][j]=f[2][j];
    115             f[2][j]=0;
    116             if(i==N) 
    117                 ANS=min(ANS,f[1][j]);
    118         }
    119     }
    120 
    121     cout<<ANS;
    122     return 0;
    123 }

     

     

  • 相关阅读:
    基本算法 st
    winServer服务器设置多用户同时远程访问!
    类的实例化顺序
    基于layui的数据列表展示数据中template的作用。使得日期等数据符合预期进行展示
    基于layui的laydate,在加载后台数据时laydate.render()不起作用。
    微信企业号两种常用搜索加载方式
    Docker搭建私有仓库registry
    第7章 Dockerfile详解
    第6章 docker数据管理
    第5章 Docker的四种网络模式
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4716185.html
Copyright © 2011-2022 走看看