POJ 1691 记忆化搜索解集合dp

来源:互联网 发布:软件开发管理制度 编辑:程序博客网 时间:2024/05/17 09:18

首先处理出来每个方块的依赖关系。每个方块上面颜色如果和他不同的话,就从上面方块往下面指一条边。

注意,他给的坐标是点,不是方块。。。

总共有15个方块 s 是一个二进制数,i 位为1代表 方块 i 被涂上颜色。

每次选择度数为 0 的方块涂色。然后跟新状态继续 dfs 。

#include <stdio.h>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <string.h>#include <stdlib.h>#include <time.h>#include <fstream>#include <set>#include <stack>using namespace std;#define READ freopen("acm.in","r",stdin)#define WRITE freopen("acm.out","w",stdout)#define ll long long#define ull unsigned long long #define PII pair<int,int>#define PDI pair<double,int>#define PDD pair<double,double>#define MII map<int,int>::iterator #define fst first#define sec second#define MS(x,d) memset(x,d,sizeof(x))#define INF 0x3f3f3f3f#define ALL(x) x.begin(),x.end()#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ROOT 0,n-1,1#define PB push_back#define FOR(a,b,c) for(int a=b;a<c;a++)#define MOD 99991#define keyTree (ch[ ch[root][1] ][0])#define MAX 1111int color[100];int n;int G[20][20];int b[111][111];int du[100];int dp[1<<15];int dfs(int s){    if(s==(1<<n)-1)        return 0;    if(dp[s]!=INF)        return dp[s];    for(int i=0;i<n;i++)    {        if((s&(1<<i))==0&&du[i]==0)        {            int ts=s;            vector<int> change;            for(int j=0;j<n;j++)            {                if(color[j]==color[i]&&du[j]==0)                {                    ts|=(1<<j);                    for(int k=0;k<n;k++)                        if(G[j][k])                            du[k]--,change.PB(k);                }            }            dp[s]=min(dp[s],dfs(ts)+1);            for(int i=0;i<change.size();i++)                du[change[i]]++;        }    }    return dp[s];}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {        MS(b,0),MS(du,0),MS(G,0),MS(dp,0x3f),MS(color,0);        scanf("%d",&n);        int maxx=-1,maxy=-1;        for(int i=0;i<n;i++)        {            int x[2],y[2],c;            scanf("%d%d%d%d%d",&x[0],&y[0],&x[1],&y[1],&c);            maxx=max(max(x[1],x[0]),maxx);            maxy=max(max(y[0],y[1]),maxy);            for(int j=x[0];j<x[1];j++)                for(int k=y[0];k<y[1];k++)                    b[j][k]=i;            color[i]=c;        }        for(int i=1;i<maxx;i++)        {            for(int j=0;j<maxy;j++)            {                if(!G[b[i-1][j]][b[i][j]]&&color[b[i-1][j]]!=color[b[i][j]])                {                    G[b[i-1][j]][b[i][j]]=1;                    du[b[i][j]]++;                }            }        }        /*        for(int i=0;i<n;i++)            cout<<du[i]<<" ";        cout<<endl<<endl;        for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)                cout<<G[i][j]<<" ";            cout<<endl;        }        */        cout<<dfs(0)<<endl;    }    return 0;}


0 0