• POJ1038


    题目大意

    要求你在N*M大小的主板上嵌入2*3大小的芯片,不能够在损坏的格子放置,问最多能够嵌入多少块芯片?

    题解

    妈蛋,这道题折腾了好久,黑书上的讲解看了好几遍才稍微有点眉目(智商捉急),接着看了网上大牛的解题报告和实现代码才弄明白怎么用三进制来进行状态压缩,关键就是理解能够横着放置和竖着放置的条件。由于竖着放置会受到前面两行的影响,这样我们就可以用三进制来表示前面两行的状态了,然后根据前面两行的状态我们也可以得到当前行与前一行的初始状态,之后再根据两个的状态进行放置砖块~~~~具体怎么样的看黑书吧

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define MAXN 15
    int dp[2][60000],pre[MAXN],now[MAXN];
    int mp[MAXN*10+5][MAXN];
    int  s[MAXN],n,m;
    int To_ten(int *a)
    {
        int ret=0;
        for(int i=1; i<=m; i++)
            ret+=a[i]*s[i];
        return ret;
    }
    void To_three(int *a,int x)
    {
        for(int i=1; i<=m; i++)
        {
            a[i]=x%3;
            x/=3;
        }
    }
    void dfs(int sum,int x,int y,int status)
    {
        dp[x][status]=max(dp[x][status],sum);
        if(y>=m) return;
        if(!pre[y]&&!pre[y+1]&&!now[y]&&!now[y+1])
        {
            now[y]=2,now[y+1]=2;
            int st=To_ten(now);
            dfs(sum+1,x,y+2,st);
            now[y]=0,now[y+1]=0;
        }
        if((y+2<=m)&&!now[y]&&!now[y+1]&&!now[y+2])
        {
            now[y]=2,now[y+1]=2,now[y+2]=2;
            int st=To_ten(now);
            dfs(sum+1,x,y+3,st);
            now[y]=0,now[y+1]=0,now[y+2]=0;
        }
        dfs(sum,x,y+1,status);
    }
    int main()
    {
        int T;
        s[0]=0,s[1]=1;
        for(int i=2; i<=12; i++)
            s[i]=s[i-1]*3;
        scanf("%d",&T);
        while(T--)
        {
            int k;
            scanf("%d%d%d",&n,&m,&k);
            memset(dp,-1,sizeof(dp));
            memset(mp,0,sizeof(mp));
            while(k--)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                mp[x][y]=1;
            }
            for(int i=1; i<=m; i++)
                pre[i]=mp[1][i]+1;
            int temp=To_ten(pre);
            dp[0][temp]=0;
            for(int i=2; i<=n; i++)
            {
                memset(dp[(i+1)&1],-1,sizeof(dp[(i+1)&1]));
                for(int j=0; j<s[m+1]; j++)
                    if(dp[i&1][j]!=-1)
                    {
                        To_three(pre,j);
                        for(int p=1; p<=m; p++)
                            if(mp[i][p])
                                now[p]=2;
                            else
                                now[p]=max(0,pre[p]-1);
                        temp=To_ten(now);
                        dfs(dp[i&1][j],(i+1)&1,1,temp);
                    }
            }
            int ans=0;
            for(int i=0; i<s[m+1]; i++)
                ans=max(ans,dp[(n+1)&1][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }

  • 相关阅读:
    git(常用命令)思维导图...
    有关gitlab的神秘操作.....version&&domain设置...
    Gitlab不小心关闭了sign-in,无法登录web的坑。。。
    聊聊CMSIS-RTOS是什么东东
    c#接口interface学习
    没有内置小鹤双拼的rime输入法就是差劲
    stm32中的型号对比——为什么很少用STM32F2,F3?
    stm32软件编程的框架及注意事项——rtos篇
    modbus-poll和modbus-slave工具的学习使用——modbus协议功能码3的解析(及欧姆龙温控器调试笔记)
    keil中error: #70: incomplete type is not allowed—解决方法
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3461234.html
Copyright © 2020-2023  润新知