zoukankan      html  css  js  c++  java
  • UCF Local Programming Contest 2017 H题(区间dp)

    这道题我们发现数据范围并不大,而且最重要的一点是,可以看的出区间dp的影子,也就是说长区间的最大值,完全可以通过两个小区间合并而来

    因此我们考虑先暴力枚举每个区间的lis。之后进行区间dp计算

    有几个注意点是,初始化的时候,只需要初始化长度至少为1的情况,在区间dp内部,有一步赋值操作

    这一步的意义是将我们求出的符合条件的lis赋值给这段区间,这样可以保证正确性,因为这道题是大于等于k的最多个数,所以答案并不一定是合并而来,比如 1 3 5 他的k=2的答案其实是3

    这也是我们要求lis的原因

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #include<algorithm>
    #include<queue>
    #include<set>
    #define ull unsigned long long
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,pair<int,int> > plll;
    const int N=1e5+10;
    const int inf=0x3f3f3f3f;
    using namespace std;
    int f[201][201][201];
    int a[N];
    int cnt[201][201];
    int lis(int l,int r){
        vector<int> num;
        int i,j;
        num.push_back(a[l]);
        for(i=l+1;i<=r;i++){
            if(a[i]>num.back())
                num.push_back(a[i]);
            else{
                int pos=lower_bound(num.begin(),num.end(),a[i])-num.begin();
                num[pos]=a[i];
            }
        }
        return num.size();
    }
    int main() {
        int i;
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            for(i=1;i<=n;i++){
                cin>>a[i];
            }
            int j;
            for(i=1;i<=n;i++){
                for(j=1;j<=n;j++){
                    cnt[i][j]=lis(i,j);
                }
            }
            memset(f,0,sizeof f);
            for(i=1;i<=n;i++){
                f[1][i][i]=1;
            }
            int l,r;
            int len;
            for(i=1;i<=cnt[1][n];i++){
                for(len=1;len<=n;len++){
                    for(l=1;l+len-1<=n;l++){
                        r=l+len-1;
                        if(cnt[l][r]>=i){
                            f[i][l][r]=cnt[l][r];
                        }
                        int k;
                        for(k=l;k<r;k++){
                            f[i][l][r]=max(f[i][l][r],f[i][l][k]+f[i][k+1][r]);
                        }
                    }
                }
            }
            for(i=1;i<n;i++){
                printf("%d ",f[i][1][n]);
            }
            cout<<f[n][1][n]<<endl;
        }
    }
    View Code
  • 相关阅读:
    linux_grep操作
    linux_awk操作
    linux_sed操作
    [题解]USACO 5.2.1 Snail Trails
    [数据生成器]UVA10054 The Necklace
    [题解]UVA10054 The Necklace
    [题解]UVA11027 Palindromic Permutation
    [题解]UVA10129 Play on Words
    [题解]UVA11029 Leading and Trailing
    计蒜客NOIP2017提高组模拟赛(五)day1-机智的 AmyZhi
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12663504.html
Copyright © 2011-2022 走看看