zoukankan      html  css  js  c++  java
  • [CEOI2002]Bugs Integrated, Inc. 题解

    又是一道神仙题,又是题解看不懂……
    好时代,来临力……


    时隔一个世纪来补题解了……
    之前太垃圾了,脑子有点问题,所以没看懂题解。今天再看这道题虽然还是很毒瘤,但也没有想象得那么难。
    先观察芯片的形状,肯定要三进制状压。所以表示一下状态:对于每一个格子 ((i,j))(0) 表示 (i-1,i-2) 行都可以放;(1) 表示 (i-1) 行可以放,(i-2) 行不行;(2) 表示 (i-1) 行不能放((i-2) 行就不用管了)。
    于是就可以由上一行的状态推出当前行的状态了:对于当前行的每一格,设上一行状态为 (x),如果 (x=0),则当前格状态为 (0);如果上一行为坏掉的点,当前状态为 (2);其他情况,当前状态为 (x-1)
    状态推出来之后用 dfs 算出当前的铺设情况。如果要以 ((x,y)) 为左下角放芯片,则有如下转移(pre[]cur[]分别表示了上一行和当前行每一格的状态):

    • 纵向放芯片,需要满足pre[y]=0 && pre[y+1]=0 && cur[y]=0 && cur[y+1]=0
    • 横向放芯片,需要满足cur[y]=0 && cur[y+1]=0

    满足条件后继续转移到下一个芯片,回溯时统计最大值。
    可以预处理出 (3) 的幂次,设计好三进制与十进制互相转化的函数。
    更多细节看代码吧。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=155,M=15,p[]={1,3,9,27,81,243,729,2187,6561,19683,59049};
    int n,m,k,f[2][60000],pre[M],cur[M];
    bool v[N][M];
    
    int TERtoDEC(int a[]) //ternary to decimal
    {
        int res=0;
        for(int i=0;i<m;++i) res+=p[i]*a[i];
        return res;
    }
    void DECtoTER(int x,int a[]) {for(int i=0;i<m;++i) a[i]=x%3,x/=3;}
    
    void dfs(int fl,int j,int last,int state)
    {
        f[fl][state]=max(f[fl][state],last);
        if(j>=m) return;
        if(j+1<m&&!pre[j]&&!pre[j+1]&&!cur[j]&&!cur[j+1])
        {
            cur[j]=cur[j+1]=2;
            dfs(fl,j+2,last+1,TERtoDEC(cur));
            cur[j]=cur[j+1]=0;
        }
        if(j+2<m&&!cur[j]&&!cur[j+1]&&!cur[j+2])
        {
            cur[j]=cur[j+1]=cur[j+2]=2;
            dfs(fl,j+3,last+1,TERtoDEC(cur));
            cur[j]=cur[j+1]=cur[j+2]=0;
        }
        dfs(fl,j+1,last,state);
    }
    
    int main()
    {
        int T; scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            memset(v,0,sizeof(v));
            for(int i=1,x,y;i<=k;++i)
                scanf("%d%d",&x,&y),v[x][y-1]=1;
            memset(f[0],-1,sizeof(f[0]));
            for(int i=0;i<m;++i) pre[i]=v[1][i]?2:1;
            int fl=0,tmp=TERtoDEC(pre);
            f[fl][tmp]=0;
            for(int i=2;i<=n;++i)
            {
                fl^=1; memset(f[fl],-1,sizeof(f[fl]));
                for(int j=0;j<p[m];++j)
                {
                    if(f[fl^1][j]==-1) continue;
                    DECtoTER(j,pre);
                    for(int k=0;k<m;++k)
                        if(v[i][k]) cur[k]=2;
                        else cur[k]=pre[k]?pre[k]-1:0;
                    tmp=TERtoDEC(cur);
                    dfs(fl,0,f[fl^1][j],tmp);
                }
            }
            int ans=0;
            for(int i=0;i<p[m];++i) ans=max(ans,f[fl][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    OSG-提示“error reading file e:1.jpg file not handled”
    OSG-加载地球文件报0x00000005错误,提示error reading file simple.earth file not handled
    QT-找开工程后,最上方提示the code model could not parse an included file, which might lead to incorrect code completion and highlighting, for example.
    我的书《Unity3D动作游戏开发实战》出版了
    java中无符号类型的第三方库jOOU
    Windows批处理备份mysql数据
    使用 DevTools 时,通用Mapper经常会出现 class x.x.A cannot be cast to x.x.A
    Java版本,Java版本MongoDB驱动,驱动与MongoDB数据库,Spring之间的兼容性
    Jrebel本地激活方法
    wget下载指定网站目录下的所有内容
  • 原文地址:https://www.cnblogs.com/wzzyr24/p/12384438.html
Copyright © 2011-2022 走看看