• XDU1131 思维+dp优化


    题意

    分析

    一个直观的做法是,枚举前两项,不断检查前一项,这需要维护一个有序数组并且带下标(可以用一个map<int,vector<int> >,将数字相同的数推倒一个vector中,vector中存的就是相同的数的位置)

    时间复杂度:O(n^2*(logn+logn))

    这个做法不太行啊,两个log,有点卡不过去

    由于有很多重复的枚举,dp优化

    dp[i][j]:以i,j为开始两个的最大长度

    转移:显然需要k且k>j的help,   a[k]=a[i]+a[j] (k>j)即可(二分即可)

    另一种dp[i][j]:以i,j为结束两个的最大长度

    转移:需要k且k<i的help   ,a[k]+a[i]==a[j](k<i)

    但这个状态不太好找二分不好check

    时间复杂度O(n^2*logn)

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <iostream>
    #include <cmath>
    #include <queue>
    #include <ctime>
    using namespace std;
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define dbg(x) cout<<#x<<" = "<< (x)<< endl
    #define pb push_back
    #define fi first
    #define se second
    #define ll long long
    #define sz(x) (int)(x).size()
    #define pll pair<long long,long long>
    #define pii pair<int,int>
    #define pq priority_queue
    vector<pll> v;
    int dp[1010][1010];
    ll a[1010];
    int main(){
        int n;
        while(scanf("%d",&n)!=EOF){
            v.clear();
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                v.pb({a[i],i});
            }
            if(n==1){
                printf("1
    %lld
    ",a[1]);
                continue;
            }
            sort(v.begin(),v.end());
            pll res;int cnt=0;
            for(int i=n-1;i>=1;i--){
                for(int j=i+1;j<=n;j++){
                    auto it=lower_bound(v.begin(),v.end(),(pll){a[i]+a[j],j+1});
                    if(it!=v.end() && it->fi==a[i]+a[j]){
                        dp[i][j]=dp[j][it->se]+1;
                    }else{
                        dp[i][j]=2;
                    }
                    if(dp[i][j]>cnt || (dp[i][j]==cnt && (pll){a[i],a[j]}<res)){
                        res={a[i],a[j]};
                        cnt=dp[i][j];
                    }
                }
            }
            printf("%d
    ",cnt);
            printf("%lld %lld",res.fi,res.se);
            for(int i=2;i<cnt;i++){
                printf(" %lld",res.fi+res.se);
                res.fi+=res.se;
                swap(res.fi,res.se);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    web测试用例表(自用)
    程序员技术练级攻略
    整理:Google jQuery 引用地址大全和方法(转)
    开发神器之--Sublime Text
    Intellij编译时报“java: System Java Compiler was not found in classpath” 解决办法
    JAVA编译异常处理:java.lang.OutOfMemoryError: PermGen space
    mongo中查询Array类型的字段中元素个数
    BigDecimal进行除法divide运算注意事项
    用来代替本机IP的万能IP:127.0.0.1
    oracle中sys和System的默认密码
  • 原文地址:https://www.cnblogs.com/Deadline/p/8977350.html
Copyright © 2020-2023  润新知