• 51Nod 1522 上下序列 —— 区间DP


    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522

    区间DP,从大往小加;

    新加入一种数有3种加法:全加左边,全加右边,一左一右;

    然后判断一下加完是否满足那些条件即可;

    但判断这个条件还挺复杂,一不小心就写丑了错了...

    冗余错误写法:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int n,m,c[105][3];
    ll f[40][80][80];
    char ch[5];
    bool ck(int a,int b,int fl)
    {
        if(fl==1)
        {
            for(int i=1,x,y;i<=m;i++)
            {
                x=c[i][1]; y=c[i][2];
                if((x==a&&y==b)||(x==b&&y==a)&&c[i][0]!=1)return 0;
                if((x==a||x==b)&&y>b&&(c[i][0]!=4&&c[i][0]!=2))return 0;
                if((y==a||y==b)&&x>b&&(c[i][0]!=5&&c[i][0]!=3))return 0;
            }
            return 1;
        }
        if(fl==0)
        {
            for(int i=1,x,y;i<=m;i++)
            {
                x=c[i][1]; y=c[i][2];
                if((x==a&&y==b)||(x==b&&y==a)&&c[i][0]!=1)return 0;
                if((x==a||x==b)&&y<a&&(c[i][0]!=4&&c[i][0]!=2))return 0;
                if((y==a||y==b)&&x<a&&(c[i][0]!=5&&c[i][0]!=3))return 0;
            }
            return 1;
        }
        if(fl==2)
        {
            for(int i=1,x,y;i<=m;i++)
            {
                x=c[i][1]; y=c[i][2];
                if((x==a&&y==b)||(x==b&&y==a)&&c[i][0]!=1)return 0;
                if((x==a||x==b)&&(y>a&&y<b)&&(c[i][0]!=4&&c[i][0]!=2))return 0;
                if((y==a||y==b)&&(x>a&&x<b)&&(c[i][0]!=5&&c[i][0]!=3))return 0;
            }
            return 1;
        }
        if(fl==4)
        {
            for(int i=1,x=c[i][1],y=c[i][2];i<=m;i++,x=c[i][1],y=c[i][2])
                if((x==a&&y==b)||(x==b&&y==a)&&(c[i][0]==2||c[i][0]==3))return 0;
            return 1;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %s %d",&c[i][1],&ch,&c[i][2]);
            if(ch[0]=='=')c[i][0]=1;
            else if(ch[0]=='<'&&ch[1]=='=')c[i][0]=4;
            else if(ch[0]=='>'&&ch[1]=='=')c[i][0]=5;
            else if(ch[0]=='<')c[i][0]=2;
            else if(ch[0]=='>')c[i][0]=3;
        }
        for(int i=1;i<2*n;i++)if(ck(i,i+1,4))f[n][i][i+1]=1;
        for(int i=n-1;i;i--)
            for(int l=1;l<=2*n;l++)
                for(int r=l+1;r<=2*n;r++)
                    if(f[i+1][l][r])
                    {
    //                    printf("i=%d l=%d r=%d
    ",i,l,r);
                        int x,y;
                        if(l>2)
                        {
                            x=l-2,y=l-1;
                            if(ck(x,y,1))f[i][x][r]+=f[i+1][l][r];
    //                                         printf("f[%d][%d][%d]=%d
    ",i,x,r,f[i][x][r]);
                        }
                        if(r+2<=2*n)
                        {
                            x=r+1,y=r+2;
                            if(ck(x,y,0))f[i][l][y]+=f[i+1][l][r];
    //                                         printf("f[%d][%d][%d]=%d
    ",i,l,y,f[i][l][y]);
                        }
                        if(l>1&&r+1<=2*n)
                        {
                            x=l-1; y=r+1;
                            if(ck(x,y,2))f[i][x][y]+=f[i+1][l][r];
    //                                         printf("f[%d][%d][%d]=%d
    ",i,x,y,f[i][x][y]);
                           }
                    }
        printf("%lld
    ",f[1][1][n<<1]);
        return 0;
    }

     于是参考了一下TJ...

    调了一小时只因把 x==b 写成 y==b ?!而且还一直没仔细看...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int n,m,c[105][3];
    ll f[80][80];
    char ch[5];
    bool ck0(int a,int b)
    {
        for(int i=1,x=c[i][1],y=c[i][2];i<=m;i++,x=c[i][1],y=c[i][2])
            if(((x==a&&y==b)||(x==b&&y==a))&&(c[i][0]==2||c[i][0]==3))return 0;
        return 1;
    }
    bool ck(int l,int r,int a,int b)
    {
        for(int i=1;i<=m;i++)
        {
            int x=c[i][1],y=c[i][2],cc=c[i][0];
            bool ix=(x==a||x==b),iy=(y==a||y==b);
            bool kx=(x>=l&&x<=r),ky=(y>=l&&y<=r);
            if(cc==1&&((ix!=iy)||(kx!=ky)))return 0;//=
            if(cc==2&&(!ky&&(ix||kx)))return 0;//<
            if(cc==3&&(!kx&&(iy||ky)))return 0;//>
            if(cc==4&&((ix&&!iy&&!ky)||(kx&&!ky)))return 0;//<=
            if(cc==5&&((iy&&!ix&&!kx)||(ky&&!kx)))return 0;//>=
        }
        return 1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        bool flag=0; int cnt=0;
        for(int i=1,x,y,cc;i<=m;i++)
        {
            scanf("%d %s %d",&x,&ch,&y);
            if(ch[0]=='=')cc=1;
            else if(ch[0]=='<'&&ch[1]=='=')cc=4;
            else if(ch[0]=='>'&&ch[1]=='=')cc=5;
            else if(ch[0]=='<')cc=2;
            else if(ch[0]=='>')cc=3;
            if(x==y)
            {
                if(cc==2||cc==3)flag=1;
                continue;//!
            }
            c[++cnt][1]=x; c[cnt][2]=y; c[cnt][0]=cc;
        }
        if(flag){printf("0
    "); return 0;}
        m=cnt;
        for(int i=1;i<2*n;i++)if(ck0(i,i+1))f[i][i+1]=1;
        for(int l=4;l<=2*n;l+=2)
            for(int i=1;i<=2*n-l+1;i++)
            {
                int j=i+l-1;
                if(ck(i+2,j,i,i+1))f[i][j]+=f[i+2][j];
                if(ck(i,j-2,j-1,j))f[i][j]+=f[i][j-2];
                if(ck(i+1,j-1,i,j))f[i][j]+=f[i+1][j-1];
            }
        printf("%lld
    ",f[1][2*n]);
        return 0;
    }
  • 相关阅读:
    打印九九乘法表
    PAT (Basic Level) Practice (中文) 1091 N-自守数 (15分)
    PAT (Basic Level) Practice (中文)1090 危险品装箱 (25分) (单身狗进阶版 使用map+ vector+数组标记)
    PAT (Basic Level) Practice (中文) 1088 三人行 (20分)
    PAT (Basic Level) Practice (中文) 1087 有多少不同的值 (20分)
    PAT (Basic Level) Practice (中文)1086 就不告诉你 (15分)
    PAT (Basic Level) Practice (中文) 1085 PAT单位排行 (25分) (map搜索+set排序+并列进行排行)
    PAT (Basic Level) Practice (中文) 1083 是否存在相等的差 (20分)
    PAT (Basic Level) Practice (中文) 1082 射击比赛 (20分)
    PAT (Basic Level) Practice (中文) 1081 检查密码 (15分)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9672540.html
Copyright © 2020-2023  润新知