博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1691 搜索
阅读量:4685 次
发布时间:2019-06-09

本文共 2738 字,大约阅读时间需要 9 分钟。

1.题意:

给你个一平板由N个矩阵组成,先Y后X,给出的点是矩阵左上角和右下角。

每个矩阵可以用一种颜色刷子粉刷,求把这平板按指定颜色全部涂色,并且该平板是竖的,当前粉刷的矩阵要保证其上面没有未粉刷的矩阵,求最少的换刷子次数?

算法:

1.根据规则建好图。

2.根据N比较少,可以用dp状态压缩或直接DFS回溯,我写的是回溯,还可以用记忆化搜索。

dp[i][j]  = c 表示最后粉刷的是第i个矩阵,已经粉刷的矩阵状态为j, 换粉刷次数为c

3. DFS 回溯

View Code
#include
#include
#include
#include
#include
#include
using namespace std;#define MAXN 1000struct Mt{ int tx,ty,bx,by,color;//左上角, 右下角 bool flag; }M[MAXN];int N, T, mp[50][50], in[50];int maxn;void build_Graph( ){ for( int i = 1; i <= N; i++) { for( int j = 1; j <= N; j++) { if( j == i ) continue; if( M[i].by == M[j].ty ) { if( !(M[j].bx < M[i].tx || M[j].tx > M[i].bx) ) { in[j]++; mp[i][j] = 1; } } } } }void color( int x ){ for( int i = 1; i <= N; i++) { if( M[i].flag || in[i] || M[i].color != x ) continue; M[i].flag = 1; for( int j = 1; j <= N; j++) { if( mp[i][j] ) in[j]--; } } }void DFS( int num ){ int i; if( num > maxn ) return; for(i = 1; i <= N; i++) { if( M[i].flag == 0 ) break; } if( i == N + 1 ) { if( num < maxn ) maxn = num; return; } int flag[30],temp[30][30],in1[30]; for( int i = 1; i <= N; i++) { if( M[i].flag || in[i] ) continue; for( int j = 1; j <= N; j++) { flag[j] = M[j].flag; in1[j] = in[j]; for( int k = 1; k <= N; k++) { temp[j][k] = mp[j][k]; } } color( M[i].color ); DFS( num + 1); for( int j = 1; j <= N; j++) { M[j].flag = flag[j]; in[j] = in1[j]; for( int k = 1; k <= N; k++) { mp[j][k] = temp[j][k]; } } } }int main( ){ scanf("%d",&T); while(T--) { scanf("%d",&N); memset(mp,0,sizeof(mp)); memset(in,0,sizeof(in)); for( int i = 1; i <= N; i++) { scanf("%d%d%d%d%d",&M[i].ty,&M[i].tx, &M[i].by,&M[i].bx, &M[i].color); M[i].flag = false; } build_Graph( ); /* for( int i = 1; i <= N; i++) printf("%d\n",in[i]); for( int i = 1; i <= N; i++) { for( int j = 1; j <= N; j++) printf("%d ",mp[i][j]); puts(""); } */ maxn = 0x7f7f7f7f; DFS( 0 ); printf("%d\n",maxn); } return 0; }

4.记忆话搜索(从网上找的别人代码,自己没写了)

View Code
#include
#include
#include
using namespace std;struct Ret{ int x1,y1,x2,y2,c;}ret[20];#define INF 1000000000int n;int dp[15][1<<15]; //dp[i][j]表示最后一个扩展的矩形是i...已扩展的矩形状态是j需要的最少数目bool used[15];int res;bool up[20][20];void init(){ memset(used,0,sizeof(used)); res=INF; memset(up,0,sizeof(up)); for(int i=0;i
=ret[j].y2)) up[i][j]=true; } for(int i=0;i
dp[last][use]) { return false; } bool ok=false; int now=INF; if(count>res) return false; for(int i=0;i

 

转载于:https://www.cnblogs.com/tangcong/archive/2012/07/30/2615445.html

你可能感兴趣的文章
类的关联、组合、聚合关系
查看>>
binary hacks读数笔记(ld 链接讲解 二)
查看>>
SKPhysicsJoint类
查看>>
在Ubuntu下编译Qt错误及处理办法
查看>>
LVS-Keepalived高可用集群(DR)
查看>>
day3_python可变的类型、不可变的类型
查看>>
数据结构(3)-线性表顺序结构的合并操作
查看>>
6个html5页面适配iphone6的技巧
查看>>
Use Slim to overview model in Tensorflow like model.summary() in Keras
查看>>
《编写高质量代码--Web前端开发修炼之道》读书笔记
查看>>
Arduino超级马里奥游戏机
查看>>
Objective-C数组
查看>>
.net开源CMS
查看>>
你懂AI吗(1)
查看>>
双拼输入法
查看>>
CentOS7 中防火墙配置
查看>>
php扩展目录
查看>>
PageRank算法
查看>>
angualrJS学习入门记录
查看>>
javascript编写一个简单的编译器(理解抽象语法树AST)
查看>>