看了大神的代码终于理清了,主要利用位运算和剪枝
代码如下
#include <cstring>
#include <cstdio>
const int maxn=20;
const int N=5;
int n,ch,w[5],jump[maxn],ans;
//w[i]代表工作单元i使用时刻的二进制表示,jump代表两个任务之间的间隔,ans代表需要的时间
int min(int x,int y){
return x>y?y:x;
}
int judge(int* a,int k){
for(int i=0;i < N ; i ++)
if((a[i]>>k)&w[i]) return false;//相邻任务之间间隔k产生冲突
return true;
}
void dfs(int* a,int d,int num){//d代表目前的任务,num代表上一个任务结束时间
if(d==10){
ans=min(num,ans);
return;
}
if(num+(10-d)*jump[0]>ans) return;//剪枝2:最好的情况下时间大于ans,剪枝
for(int i=0; i < ch ; i++) {
if(judge(a,jump[i])){
int p[N];
for(int j=0; j < N ; j++)
p[j]=(a[j]>>jump[i])^w[j];
dfs(p,d+1,num+jump[i]);
}
}
}
int main(){
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)==1&&n){
memset(w,0,sizeof(w));
ans=n*10;
char c[30];
for(int i=0;i < N;i++){
scanf("%s",c);
for(int k=0;k < n;k++)
if(c[k]=='X')
w[i]|=1 << k;
}
ch=0;
for(int k=0;k<=n;k++){
if(judge(w,k)) jump[ch++]=k;//剪枝1:记录所有可能的间隔距离
}
dfs(w,1,n);
printf("%d\n",ans);
}
return 0;
}