zoukankan      html  css  js  c++  java
  • luogu P1398 [NOI2013]书法家

    传送门

    注意到(N O I)三个字母都可以从左到右拆成三部分,即(N=)一个矩形+一堆矩形+一个矩形,(O=)一条+两条横的+一条,(I=)两条横的+一个矩形+两条横的,所以可以拆成(13)个部分转移((9)个字母部分,(4)个空白部分)

    (f_{i,j,l,r})表示第(i)列,放的是字母的(j)部分,放了从(l)行到(r)行的最大值,(g_{i,j})表示第(i)列,放的是的空白(j)部分的最大值.转移根据不同的部分,枚举下一列怎么放,但是这样复杂度不对.可以发现只有空白部分转移到字母部分和(N)部分转移需要枚举放哪里,其他的可以直接继承上一个状态的(l,r)

    空白部分转移比较简单,这里主要看(N).首先从第一部分转移到第二部分,如果放了(l,r),那么前一个状态的后面两维为(l,r'(r'>r)),所以可以记后缀最大值直接转移.然后是第二部分之间的转移,上一个状态后两维是(l',r'(l'ge l,l-1le r'le r)),这个也可以前缀最值优化.从第二部分转移到第三部分,前一个状态的后面两维为(l',r(l'<l)),可以前缀最值优化

    具体细节详见代码

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    #define il inline
    
    using namespace std;
    const int N=150+10,M=500+10;
    il int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,m,a[N][M],s[N][M],f[2][10][N][N],g[2][4],ss[N];
    
    int main()
    {
        n=rd(),m=rd();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                a[i][j]=rd(),s[i][j]=s[i-1][j]+a[i][j];
        memset(f,-0x3f,sizeof(f)),memset(g,-0x3f,sizeof(g));
        int nw=1,la=0;
        g[la][0]=0;
        for(int j=1;j<=m+1;++j)
        {
            memcpy(g[nw],g[la],sizeof(g[la]));
            //
            for(int l=1;l<=n;++l)
                for(int r=l+1;r<=n;++r)
                    f[nw][1][l][r]=max(g[la][0],f[la][1][l][r])+s[r][j]-s[l-1][j];
            for(int l=1;l<=n;++l)
                for(int r=n,mx=-(1<<29);r>=l;--r)
                {
                    f[nw][2][l][r]=max(f[nw][2][l][r],mx+s[r][j]-s[l-1][j]);
                    mx=max(mx,f[la][1][l][r]);
                }
            memset(ss,-0x3f,sizeof(ss));
            for(int l=1;l<=n;++l)
                for(int r=l,mx=ss[l-1];r<=n;++r)
                {
                    ss[r]=max(ss[r],f[la][2][l][r]);
                    mx=max(mx,ss[r]);
                    f[nw][2][l][r]=max(f[nw][2][l][r],mx+s[r][j]-s[l-1][j]);
                }
            for(int r=n;r;--r)
                for(int l=r,mx=-(1<<29);l;--l)
                {
                    f[nw][3][l][r]=max(f[nw][3][l][r],mx+s[r][j]-s[l-1][j]);
                    mx=max(mx,f[la][2][l][r]);
                }
            for(int l=1;l<=n;++l)
                for(int r=l+1;r<=n;++r)
                {
                    f[nw][3][l][r]=max(f[nw][3][l][r],f[la][3][l][r]+s[r][j]-s[l-1][j]);
                    g[nw][1]=max(g[nw][1],f[la][3][l][r]);
                }
            //
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                    f[nw][4][l][r]=g[la][1]+s[r][j]-s[l-1][j];
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                    f[nw][5][l][r]=max(f[la][4][l][r],f[la][5][l][r])+a[l][j]+a[r][j];
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                {
                    f[nw][6][l][r]=f[la][5][l][r]+s[r][j]-s[l-1][j];
                    g[nw][2]=max(g[nw][2],f[la][6][l][r]);
                }
            //
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                    f[nw][7][l][r]=max(g[la][2],f[la][7][l][r])+a[l][j]+a[r][j];
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                    f[nw][8][l][r]=max(f[la][7][l][r],f[la][8][l][r])+s[r][j]-s[l-1][j];
            for(int l=1;l<=n;++l)
                for(int r=l+2;r<=n;++r)
                {
                    f[nw][9][l][r]=max(f[la][8][l][r],f[la][9][l][r])+a[l][j]+a[r][j];
                    g[nw][3]=max(g[nw][3],f[la][9][l][r]);
                }
            //
            memset(f[la],-0x3f,sizeof(f[la])),memset(g[la],-0x3f,sizeof(g[la]));
            nw^=1,la^=1;
        }
        printf("%d
    ",g[la][3]);
        return 0;
    }
    
  • 相关阅读:
    paip.提升用户体验c++ 右键菜单以及socket接口
    paip. 'QObject::QObject(const QObject&)' is private问题的解决.
    paip.ollydbg 设置c++ qt API断点总结
    paip.提升用户体验c++ qt自定义窗体(1)标题栏的绘制
    paip.提升用户体验c++ QPushButton按钮控件透明以及不规则按钮以及 鼠标越过动态设置
    paip.c++ static 变量的定义以及使用...
    paip.c++ gcc 不能捕获exception异常的解决
    paip.pyqt python qt 最新版本环境最佳实践
    paip.提升用户体验c++ QLabel标签以及QLineEdit文本框控件透明 设置
    paip.c++ 宏的展开调试.
  • 原文地址:https://www.cnblogs.com/smyjr/p/10802409.html
Copyright © 2011-2022 走看看