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;
}