CodeForces - 1198A MP3(尺取)
題目鏈接:點(diǎn)擊查看
題目大意:給出n個數(shù)字,表示不同的數(shù)據(jù),現(xiàn)在我們需要對數(shù)據(jù)進(jìn)行壓縮,壓縮的規(guī)則是:
現(xiàn)在給出一個I,表示內(nèi)存大小為,n個數(shù)字中,相同的數(shù)據(jù)可以占用同一片內(nèi)存,不同的數(shù)據(jù)必須占用不同的內(nèi)存
在以上前提下,我們需要確定一個范圍[l,r],這個區(qū)間不是數(shù)組的下標(biāo),而是數(shù)字的范圍,然后對n個數(shù)進(jìn)行操作:
現(xiàn)在我們需要求出在滿足上述所有條件的情況下,n-(r-l+1)的最小值
題目分析:這個題就在讀題上廢了好大的功夫,簡單來說為了讓n-(r-l+1)盡量小,那么就要讓r-l+1盡量大,也就是讓整個區(qū)間盡量長,因?yàn)閇l,r]他不是數(shù)組的下標(biāo),但我們可以將其轉(zhuǎn)換為數(shù)組的下標(biāo)來處理,其實(shí)就是對原數(shù)組排個序就好了,然后[l,r]就可以當(dāng)下標(biāo)來用了,首先我們必須知道,若想讓r-l+1盡可能的大,那么就必須讓區(qū)間[l,r]之間不同數(shù)字的個數(shù)恰好等于K才行,這算一種貪心的策略吧,顯而易見?在處理之前,我們先求出來K來表示上面內(nèi)存大小公式的計算結(jié)果,若K大于等于n個數(shù)中不同數(shù)字的個數(shù),那么直接輸出0即可,根本不用壓縮了,而且注意一下當(dāng)I求出來的指數(shù)很大的時候,大概大于20的時候,我們就可以直接輸出0了,因?yàn)?的20次方已經(jīng)大于1e6了,比n都大了,肯定滿足條件
在判斷完上述情況之后,剩下的我們可以用尺取法跑一邊整個數(shù)組,這個尺取需要仔細(xì)設(shè)計一下,因?yàn)樗瞧胀ㄇ蠛统呷〉囊环N小變形,我們先用一個數(shù)組維護(hù)一下前綴和,但這個前綴和維護(hù)的是0~i中不同數(shù)字的個數(shù),然后跑尺取的時候讓r一直遞增,讓l隨著r根據(jù)K來移動就行了,總的時間復(fù)雜度是n+n,也就是O(n),常數(shù)是2,具體實(shí)現(xiàn)看代碼吧
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4e5+100;int a[N],b[N];int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n,I;scanf("%d%d",&n,&I);for(int i=1;i<=n;i++)scanf("%d",a+i);I=I*8/n;int k=I>20?(1<<20):(1<<I);sort(a+1,a+1+n);a[0]=-1;//因?yàn)閍[i]的取值范圍會涉及到0,所以我們初始化一個一定與a[i]不相等的數(shù) for(int i=1;i<=n;i++){if(a[i]==a[i-1])b[i]=b[i-1];elseb[i]=b[i-1]+1;}if(k>=b[n])//特判一下return 0*printf("0");int ans;int l=1,r=1;int mmin=inf;while(r<=n)//尺取{ans=b[r++]-b[l]+1;//先求出當(dāng)前范圍內(nèi)有多少個不同的數(shù)if(ans>k)//如果這個值大于內(nèi)存K的話,就讓l逼近r{ans-=b[l++];while(ans>k)//持續(xù)逼近{ans+=b[l++];//注意要將之前的值加回來ans-=b[l];//然后再減去當(dāng)前位置的值}}if(ans==k)//如果滿足條件,更新答案mmin=min(mmin,n-(r-l));}printf("%d\n",mmin);return 0; }?
總結(jié)
以上是生活随笔為你收集整理的CodeForces - 1198A MP3(尺取)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 3488 Tour(二分图最
- 下一篇: CodeForces - 1000D Y