• 2019牛客暑假多校赛(第二场) F和H(单调栈)


    F-Partition problem

    https://ac.nowcoder.com/acm/contest/882/F

    题意:输入一个数n,代表总共有2n个人,然后每个人对所有人有个贡献值,然后问题需要将2n个人分成两组,每组n个人,问如何分组使得两组之间的价值最大,同组人不算价值。

    思路:直接dfs暴力分组。

    //aeha
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    typedef unsigned long long int ull;
    const int inf = 0x3f3f3f3f;
    int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
    #define pi acos(-1)
    #define ls rt<<1
    #define rs rt<<1|1
    #define me0(s) memset(s,0,sizeof(s))
    #define me1(s) memset(s,1,sizeof(s))
    #define mef(s) memset(s,-1,sizeof(s))
    #define meinf(s) memset(s,inf,sizeof(s))
    const int N=105;
    ll ans;
    int n;
    int t1[30],t2[30];
    int a[N],b[N],v[N][N];
    inline int read() {
        char c=getchar(); int x=0, f=1;
        while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    ll q_pow(ll a,ll b,ll mod){
        ll anss=1;
        while(b){
            if(b&1) anss=anss*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return anss;
    }
    ll q_mul(ll a,ll b,ll mod){
        ll anss=0;
        while(b){
            if(b&1) anss=(anss+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return anss;
    }
    void dfs(int pos,int cnt1,int cnt2,ll ret){
    // pos表示当前搜的人的序号,cnt1表示第一组的人数,cnt2表示第二组的人数,ret表示贡献
        if(cnt1==cnt2&&cnt1==n){
            ans=max(ans,ret);
            return ;
        }
        ll tmp=0;
        if(cnt1<n){
            for(int i=0;i<cnt2;i++){
                tmp+=v[pos][t2[i]];
            }
            t1[cnt1]=pos;
            dfs(pos+1,cnt1+1,cnt2,ret+tmp);
        }
        tmp=0;
        if(cnt2<n){
            for(int i=0;i<cnt1;i++){
                tmp+=v[pos][t1[i]];
            }
            t2[cnt2]=pos;
            dfs(pos+1,cnt1,cnt2+1,ret+tmp);
        }
    }
    int main(int argc, char * argv[]) 
    {
        std::ios::sync_with_stdio(false);
        cin>>n;
        ans=0;
        for(int i=0;i<2*n;i++){
            for(int j=0;j<2*n;j++){
                cin>>v[i][j];
            }
        }
        dfs(0,0,0,0);
        cout<<ans<<endl;
        return 0;
    }

    H-Second Large Rectangle

    https://ac.nowcoder.com/acm/contest/882/H

    题意:给定一个n*m的矩阵,其中全由0,1两个数字组成,问找到的第二大的全由1组成的矩阵的面积是多少。

    思路:先用单调栈的求第一大矩阵的模板,然后在后面的时候修改一下 ,将各种状态保存下来,注意去重。然后输出第二大的面积就行。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    typedef unsigned long long int ull;
    const int inf = 0x3f3f3f3f;
    #define pi acos(-1)
    #define ls rt<<1
    #define rs rt<<1|1
    #define me0(s) memset(s,0,sizeof(s))
    #define me1(s) memset(s,1,sizeof(s))
    #define mef(s) memset(s,-1,sizeof(s))
    #define meinf(s) memset(s,inf,sizeof(s))
    const int N=1005;
    char a[2060][2060];
    int h[2060];
    int L[2060],R[2060];
    map<int,int> ma;
    bool v[1005][1005];
    inline int read() {
        char c=getchar(); int x=0, f=1;
        while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    ll q_pow(ll a,ll b,ll mod){
        ll anss=1;
        while(b){
            if(b&1) anss=anss*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return anss;
    }
    ll q_mul(ll a,ll b,ll mod){
        ll anss=0;
        while(b){
            if(b&1) anss=(anss+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return anss;
    }
    int main(int argc, char * argv[]) 
    {
        std::ios::sync_with_stdio(false);
        int n,m;
        while(cin>>n>>m){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    cin>>a[i][j];
                }
            }
            int maxn=0;
            for(int i=1;i<=n;i++){
                me0(v);
                for(int j=1;j<=m;j++){
                    if(a[i][j]=='1')
                        h[j]++;
                    else h[j]=0;
                }
                h[0]=h[m+1]=-1;
                stack<int>s;
                for(int j=1;j<=m;j++){
                    L[j]=0;
                    if(s.size()==0){
                        s.push(j);
                        L[j]=j;
                    }
                    else{
                        while(s.size()>0&&h[s.top()]>=h[j])
                            s.pop();
                        if(s.size()==0) L[j]=1;
                        else L[j]=s.top()+1;
                        s.push(j);
                    }
                }
                while(!s.empty()){
                    s.pop();
                }
                for(int j=m;j>=1;j--){
                    R[j]=m;
                    if(s.size()==0){
                        s.push(j);R[j]=j;
                    }
                    else{
                        while(s.size()>0&&h[s.top()]>=h[j])s.pop();
                        if(s.size()==0)R[j]=m;
                        else R[j]=s.top()-1;
                        s.push(j);
                    }
                }
                for(int j=1;j<=m;j++){
                if(!v[L[j]][R[j]]){
                        ma[h[j]*(R[j]-L[j]+1)]++;
                        v[L[j]][R[j]]=1;
                        ma[h[j]*(R[j]-L[j])]++;
                        ma[(h[j]-1)*(R[j]-L[j]+1)]++;
                    }
                    if(h[j]*(R[j]-L[j]+1)>maxn)
                        maxn=h[j]*(R[j]-L[j]+1);
                }
            }
               int flag=0,ans,pos;
            for(int i=maxn;i>=0;i--){
                if(ma[i]&&ma[i]>1){
                    ans=i;
                    flag=1;
                    break;            
                }
                else if(ma[i]&&ma[i]==1){
                    pos=i;
                    break;
                }
            }
            if(flag) cout<<ans<<endl;
            else{
                for(int i=pos-1;i>=0;i--){
                    if(ma[i]){
                        ans=i;
                        break;
                    }
                }
                cout<<ans<<endl;
            } 
        }
        return 0;
    }
  • 相关阅读:
    scrollView(3)-相册浏览简单的缩放
    ScrollView(2)轮播图-点击跳转
    定制单元格-cell
    模态视图present
    将博客搬至CSDN
    VBS进行http请求及JSON数据的读取和生成
    igraph安装(R/Python)
    teiid入门
    漫谈设计模式
    MapReduce实例-基于内容的推荐(一)
  • 原文地址:https://www.cnblogs.com/wushengyang/p/11224403.html
Copyright © 2020-2023  润新知