8.5算法設計與優化策略

構造法。

很多時候可以通過直接構造法的方法來解決問題,這是最沒有規律可循的一種方法,也是最考驗“真功夫”的

例題:Gergovia的酒交易

分析:考慮最左邊的村莊。如果需要買酒,即a1>0,則一定有勞動力從村莊2忘村莊1運,而不管這些酒是哪裏來的。這樣問題就等價於只有2~N,且第二個村莊的需求量爲a1+a2

int main()
{
    int n;
    while(cin>>n&&n){
        long long ans=0,a,last=0;
        for(int i=0;i<n;i++){
            cin>>a;
            ans+=ans(last);
            last+=a;
        }
        cout<<ans<<"\n";
    }
    return 0;
}

掃描法。

掃描法類似於一種帶有順序的枚舉法,例如,從左到右考慮數組的各個元素,也可以說是從左到右的掃描,他和普通枚舉法的區別是,掃描法往往在枚舉時維護一些重要的量,從而簡化計算

例題:唯一的雪花

#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;

const int maxn=1000000+5;
int A[maxn];

int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&A[i]);
        
        set<int>s;
        int L=0,R=0,ans=0;
        while(R<n){
            while(R<n&& !s.count(A[R])) s.insert(A[R++]);
            ans=max(ans,R-L);
            s.erase(A[L++]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

另一個方法

#include<cstdio>
#include<map>
using namespace std;

const int maxn=100000+5;
int A[maxn],last[maxn];
map<int,int>cur;

int main(){
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        cur.clear();
        for(int i=0;i<n;i++){
            scanf("%d",&A[i]);
            if(!cur.count(A[i])) last[i]=-1;
            else last[i]=cur[A[i]];
            cur[A[i]]=i;
        }
        int L=0,R=0,ans=0;
        while(R<n){
            while(R<n&&last[R]<L)
                R++;
            ans=max(ans,R-L);
            L++;
        }
        printf("%d\n",ans);
    }
    return 0;
}



發佈了38 篇原創文章 · 獲贊 2 · 訪問量 8034
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章