1. 程式人生 > >UVA690-Pipeline Scheduling(dfs+二進制壓縮狀態)

UVA690-Pipeline Scheduling(dfs+二進制壓縮狀態)

cstring 沒有 pipe ... 方向 accep acc min sch

Problem UVA690-Pipeline Scheduling

Accept:142 Submit:1905

Time Limit: 3000 mSec

技術分享圖片 Problem Description

技術分享圖片

技術分享圖片 Input

技術分享圖片

技術分享圖片 Output

技術分享圖片

技術分享圖片 Sample Input

7
X...XX.
.X.....
..X....
...X...
......X
0

技術分享圖片 Sample Ouput

34

題解:dfs的思路不難,剪枝也很容易想到,最優化剪枝。這個題主要是實現時的技巧性比較強。一開始沒有想到只存階段性的表,直接最大5*200,根本就不會往二進制的方向去想,看到別人題解的標題時二進制才意識到這一點,對於每一次搜索到的下一個可能的合理位置,當要繼續遞歸下去時,這一次找到的合理位置和上一次的起始位置之間的表就已經沒有意義了(對於這個方向繼續向下的遞歸來說),直接位運算刪掉即可,這樣每時每刻都至多是5*20,開個int s[5]即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 
 6 using namespace std;
 7 
 8 const int N = 5,maxn = 25;
 9 
10 int n,cnt,Min;
11 int table[N],skip[maxn];
12 
13 bool Judge(int *num,int step){
14     for(int i = 0;i < N;i++){
15 if((num[i]>>step)&table[i]) return false; 16 } 17 return true; 18 } 19 20 void init(){ 21 memset(table,0,sizeof(table)); 22 char str[maxn]; 23 cnt = 0,Min = n*10; 24 25 for(int i = 0;i < N;i++){ 26 scanf("%s",str); 27 for(int j = 0;j < n;j++){
28 if(str[j] == X) table[i] |= (1<<j); 29 } 30 } 31 32 for(int i = 0;i <= n;i++){ 33 if(Judge(table,i)) skip[cnt++] = i; 34 } 35 } 36 37 void dfs(int *s,int d,int time){ 38 if(d == 10){ 39 Min = min(Min,time); 40 return; 41 } 42 43 if(time+skip[0]*(10-d) > Min) return; 44 45 for(int i = 0;i < cnt;i++){ 46 if(Judge(s,skip[i])){ 47 int tmp[N]; 48 for(int j = 0;j < N;j++){ 49 tmp[j] = ((s[j]>>skip[i]) | table[j]); 50 } 51 dfs(tmp,d+1,time+skip[i]); 52 } 53 } 54 } 55 56 int main() 57 { 58 #ifdef GEH 59 freopen("input.txt","r",stdin); 60 #endif 61 while(~scanf("%d",&n) && n){ 62 init(); 63 dfs(table,1,n); 64 printf("%d\n",Min); 65 } 66 return 0; 67 }

UVA690-Pipeline Scheduling(dfs+二進制壓縮狀態)