? 區(qū)間原地劃分時可以觀察相鄰元素之間的大小關(guān)系是否與劃分有關(guān)。前綴和與差分實現(xiàn)單位時間內(nèi)區(qū)間數(shù)值整體加1。(ccf-csp第二題真的很愛考前綴和。)
創(chuàng)新互聯(lián)從2013年開始,先為泊頭等服務(wù)建站,泊頭等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為泊頭企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。前綴和詳解:
一、題目要求題目描述
A1,A2,?,An?是一個由?n?個自然數(shù)(非負(fù)整數(shù))組成的數(shù)組。我們稱其中?Ai,?,Aj?是一個非零段,當(dāng)且僅當(dāng)以下條件同時滿足:
下面展示了幾個簡單的例子:
現(xiàn)在我們可以對數(shù)組?A?進(jìn)行如下操作:任選一個正整數(shù)?p,然后將?A?中所有小于?p?的數(shù)都變?yōu)?0。試選取一個合適的?p,使得數(shù)組?A?中的非零段個數(shù)達(dá)到大。若輸入的?A?所含非零段數(shù)已達(dá)大值,可取?p=1,即不對?A?做任何修改。
輸入格式
從標(biāo)準(zhǔn)輸入讀入數(shù)據(jù)。
輸入的第一行包含一個正整數(shù)?n。
輸入的第二行包含?n?個用空格分隔的自然數(shù)?A1,A2,?,An。
輸出格式
輸出到標(biāo)準(zhǔn)輸出。
僅輸出一個整數(shù),表示對數(shù)組?A?進(jìn)行操作后,其非零段個數(shù)能達(dá)到的大值。
樣例1輸入
11
3 1 2 0 0 2 0 4 5 0 2
Data
樣例1輸出
5
二、我的解法(70)#includeusing namespace std;
const int N=1e5;
int a[N],b[N];
bool st[N];//該值是否曾經(jīng)出現(xiàn)過
int main(){
int n;
cin>>n;
int num=0;
for(int i=0;i=b[i]){
res++;
//cout<=b[i]) j++;//移動到下一個0
}
}
if(res>ans) ans=res;
}
cout<
分析:
? 注意到 p 只有取到了數(shù)組中的值非零段的劃分才會發(fā)生變化,依此減少了外層循環(huán)的循環(huán)次數(shù),但是找不到p的取值和數(shù)組之間的關(guān)系,雙重循環(huán)還是超時。萬萬沒想到,又考了前綴和。
三、滿分解法#includeusing namespace std;
const int N=5e5+5,M=1e4;//N一定要開夠了,不開夠還是超時
int a[N],b[M];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]>a[i-1]){//a[i-1]到a[i]-1段的p都能構(gòu)成新的非零段
b[a[i]]--;//處理差分?jǐn)?shù)組以實現(xiàn)區(qū)間整體+1
b[a[i-1]]++;
}
}
int ans=0;
for(int i=1;i<=M;i++){
b[i]+=b[i-1];//求前綴和
if(b[i]>ans) ans=b[i];//記錄前綴和數(shù)組中的大值
}
cout<
分析:
? 當(dāng)a[i]>a[i-1]時,只要p取到區(qū)間a[i-1]到a[i]-1中的值,都能構(gòu)成一個新的非零段。這就是p與數(shù)組的關(guān)系,根據(jù)這個關(guān)系利用前綴和與差分實現(xiàn)單位時間內(nèi)區(qū)間數(shù)值整體加1,將雙重循環(huán)改進(jìn)至單層,降低計算時間。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧