cf 633 div2 c(贪心)

C. Powered Addition

传送门(题目地址)http://codeforces.com/contest/1339/problem/C
在这里插入图片描述

Input

3
4
1 7 6 5
5
1 2 3 4 5
2
0 -4

Output

2
0

3

在这里插入图片描述

题意:

本题要求你把数组变成递增。每分钟可以选择任意数组元素增加2^(n-1);求花费最少的时间,

思路

1. 由于数据量很大,所以只能想办法在o(n)内解决。即遍历数组。
2. 那就先从第1个元素开始遍历,如果找到不满足题意得,那就说明这点时要进行操作得,(a[i]<a[i-1])所以对这一点贪心得操作,(根据等比数列:首项是1,公比是2。这个数列可以从中构成任意数正整数->那么就贪心的把这个不满足的a[i]增加为a【i-1】)
3. 一个数组元素所能改变的最大值就是过的时间 t 对应的等比数列前n想和
4. 因为是对任意数组元素操作,所以线性操作,把i->更新ans后,后面的元素如果时间不够,再增加ans(时间)
5. 而如何算时间呢,我先打了个表,把等比数列前n项和 的1~64的值打印 出来。
6. 具体看我的while操作,以标记出来,
7. ans就是时间了

AC代码

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll a[maxn];
ll time[maxn];
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    ll temp=1;
    for(int i=1; i<=60; i++)
    {
        temp*=2;
        time[i]=temp-1;
    }
   int t;
   cin>>t;
   while(t--)
   {
       int n;
       cin>>n;
       for(int i=1; i<=n; i++)cin>>a[i];
       ll pre=a[1];//前一个元素
       ll ans=0;
       ll temp=0;
       for(int i=2; i<=n; i++)
       {
           if(a[i]<pre)
           {
               temp=a[i]+time[ans];
               while(temp<pre)//对a【i】进行操作,直到它大于pre
               {
                   ans++;//加了后还小,才会循环,不够,就再加一秒
                   temp=a[i]+time[ans];
               }
           }
           else pre=a[i];
       }
       cout<<ans<<endl;
   }
    return 0;
}
发布了8 篇原创文章 · 获赞 8 · 访问量 75

猜你喜欢

转载自blog.csdn.net/qq_45377553/article/details/105495785