zoukankan      html  css  js  c++  java
  • 1050 棋盘染色 2

    1050 棋盘染色 2

    题目描述 Description

    有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。

    输入描述 Input Description

    第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

    输出描述 Output Description

    第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

    样例输入 Sample Input

    5
    11100
    11000
    10000
    01111
    11111

    样例输出 Sample Output

    1

    数据范围及提示 Data Size & Hint

    N(<=100)

    轮廓型DP,又名插头DP。

    这道题用广度记忆化搜索和插头DP,逐个格子递推。

    #include <iostream>

    #include <cstring>

    #define ref(i,x,y) for(int i=x;i<=y;i++)

    #define get(t,k) (((t)>>(2*(5-(k))))%4)

    #define aj (1<<2*(5-(y)))

    using namespace std;

    int n,h,t,judx,judy;

    int a[101][6],f[102][6][1025];

    struct qmem{int x,y,s;}q[500001];

    void init(){h=t=0;memset(f,1,sizeof f);}

    void push(int x,int y,int s,int v){

           if (f[x][y][s]<=v)return;

           if (s==0&&(x*5+y<=judx*5+judy)&&q[h].s>0)return;

           t++;q[t].x=x;q[t].y=y;q[t].s=s;f[x][y][s]=v;

    }

    int getp(int s){

           bool p[6];memset(p,0,sizeof p);

           ref(i,1,5)p[get(s,i)]=1;ref(i,1,5)if(!p[i])return i;

    }

    int ch(int s,int w2,int w1){

           ref(i,1,5)if((s>>2*(i-1))%4==w2)s+=(1<<2*(i-1))*(w1-w2);

           return s;

    }

    bool only(int s,int w,int o){

           if (w==0)return 0;

           bool b=0;

           ref(i,1,5)if(get(s,i)!=w&&get(s,i)>0)b=1;

           ref(i,o+1,5)if(get(s,i)==w)b=0;

           ref(i,1,o-1)if(get(s,i)==w)b=0;

           return b;

    }

    bool ok(int s){

           int jud=0;

           ref(i,1,5)if(get(s,i)!=jud&&get(s,i)>0){

                  if(jud==0)jud=get(s,i);else return 0;}

           return 1;

    }

    int main()

    {

           cin>>n;

           ref(i,1,n)

           {

                  char s[6];cin>>s;

                  ref(j,0,4)a[i][j+1]=s[j]-48;

           }

           ref(i,1,n)ref(j,1,5)if(a[i][j]){judx=i;judy=j;}

           init();push(1,1,0,0);

           while(h<t)

           {

                  h++;

                  if(q[h].x>n)continue;

                  int x,y,s,ff,w1,w2,ts;

                  x=q[h].x;y=q[h].y;s=q[h].s;ff=f[x][y][s];

                  w1=get(s,y-1);w2=get(s,y);ts=s-aj*w2;

                  bool judge=0;

                  if ((only(s,w1,y-1)&&x==n)||only(s,w2,y)||a[x][y])judge=1;

                  if (a[x][y])ff--;

                  if(y<5)

                  {

                         if (!judge)push(x,y+1,ts,ff);

                         if(w1==0&&w2==0)push(x,y+1,ts+aj*getp(s),ff+1);else

                         if(w1==0&&w2>0)push(x,y+1,s,ff+1);else

                         if(w1>0&&w2==0)push(x,y+1,ts+aj*w1,ff+1);else

                         push(x,y+1,ch(s,w2,w1),ff+1);

                  }else{

                         if (!judge)push(x+1,1,ts,ff);

                         if(w1==0&&w2==0)push(x+1,1,ts+aj*getp(s),ff+1);else

                         if(w1==0&&w2>0)push(x+1,1,s,ff+1);else

                         if(w1>0&&w2==0)push(x+1,1,ts+aj*w1,ff+1);else

                         push(x+1,1,ch(s,w2,w1),ff+1);

                  }

           }

           int ans=f[n+1][1][0];

           ref(i,1,1024)if(ok(i)&&ans>=f[n+1][1][i]){

                  ans=min(ans,f[n+1][1][i]);

                  //cout<<i<<" "<<ans<<endl;

           }

           cout<<ans;

    }

  • 相关阅读:
    python接口自动化问题解决
    python+selenium之测试报告自动化测试实例
    python+selenium之邮件发送
    python+selenium之测试报告
    Python自动发动邮件
    安卓下H5弹窗display:table的bug
    IOS中position:fixed弹出框中的input出现光标错位的问题
    display:table-cell的应用
    :after伪类+content经典应用举例
    不同CSS技术及其CSS性能
  • 原文地址:https://www.cnblogs.com/xiaoningmeng/p/5904144.html
Copyright © 2011-2022 走看看