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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章