09-06 HDU_Steps4.3 DFS剪枝 HDU1010 HDU1016 HDU1426 HDU1455 HDU2510 HDU2553 HDU3290 HDU2616

HDU_Steps 4.3 DFS剪枝


4.3.1 HDU1010 Tempter of the Bone

具體剪枝在這篇文章有寫http://blog.csdn.net/swm8023/article/details/6731109


4.3.2 HDU1016 Prime Ring Problem

直接搜就可以了,先打好40以內的素數表


4.3.3 HDU1426 Sudoku Killer

也是赤果果的搜索+回溯,對每個未填的點枚舉1~9,然後判斷所在列,所在行,以及所在九宮格是否有重複的沒有任何剪枝170MS.


4.3.4 HDU1455 Sticks

比較經典的一道剪枝

首先要枚舉長度,從最長一根的長度開始枚舉,並且從大到小放置樹枝

另外注意的就是會有很多長度相同的樹枝,當然,對於這樣的樹枝,如果一根不滿足條件,其它的也不會滿足了

當然,這道題的剪枝還有不少,網上有大牛給出了各種剪枝,這裏的兩個剪枝對於這道題已經足夠了~

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
int st[70],n,sum,len;
bool use[70]; 
bool dfs(int cnt,int rlen,int sts){//總剩餘長度,該根剩下的長度,剩下的根數 
	if(rlen==0){
		sts--;
		if(sts==0)return true;
		//找出當前未用的最長根作爲開始 
		for(cnt=n;use[cnt];cnt--);
		use[cnt]=true;
		if(dfs(cnt-1,len-st[cnt],sts))return true;
		use[cnt]=false;
		sts++;
	}else{
		for(int i=cnt;i>=1;i--){
			if(i<n&&st[i]==st[i+1]&&!use[i+1])continue;//同樣長度的不行,這根同樣不行 
			
			if(!use[i]&&rlen>=st[i]){
				use[i]=true;
				if(dfs(i-1,rlen-st[i],sts))return true;
				use[i]=false;	
			}
		
		}
	}
	return false;
}
int main(){
	while(scanf("%d",&n),n){
		sum=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&st[i]);
			sum+=st[i];	
		}
		sort(st+1,st+n+1);
		
		for(len=st[n];len<=sum;len++){
			if(sum%len!=0)continue;
			memset(use,false,sizeof use);
			if(dfs(n,len,sum/len)){
				printf("%d\n",len);
				break;	
			}	
		}
		
	}
	return 0;	
} 

4.3.5 HDU2510 符號三角形

寫了個位運算搜索,果斷超時啊..一看範圍只有24,可恥的打表過了..

感覺這題可能是DP方法吧..搜索肯定是掛了..先放着,有時間再研究.


4.3.6 HDU2553 N皇后問題

看到這題就想到了67大牛的那篇文章,牛啊..短小精悍的程序

用row,ld,rd分別表示列上,左對角線上,右對角線上不能放的位置,full表示全部放滿的狀態..用樹狀數組的lowbit操作取出pos中的每一個1,也就是每一個能放的位置,然後繼續搜索,左對角線和右對角線向下一行搜索時要分別右移或者左移一位

#include <cstdio>
using namespace std;
int n,res,full,ans[11];
void dfs(int row,int ld,int rd){
	int pos,p;
	if(row!=full){
		pos=full&~(row|ld|rd);
		while(pos){
			p=pos&-pos;
			pos-=p;
			dfs(row|p,(ld|p)<<1,(rd|p)>>1);	
		}
	}else res++;	
}

int main(){
	for(int i=1;i<=10;i++){
		res=0;
		full=(1<<i)-1;
		dfs(0,0,0);
		ans[i]=res;			
	}
	while(scanf("%d",&n),n){
		printf("%d\n",ans[n]); 
	}
	return 0;	
} 


4.3.7 HDU3290 The magic apple tree

暈,看題目看了好久纔看懂,一棵樹中,第一天只有子節點開花(不記得是不是開花,反正是這個意思),數量等於節點標記,一個父節點只有當它的所有子節點都開花時纔會開花,數量等於子節點的(K+1)/2

這題不能說是搜索吧,更有點像樹形DP..

樹是連續讀入的,所有節點存在v中,num表示子節點個數,注意沒有說明根節點!!!要先找到根,因爲這個一直TLE,鬱悶

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
int first[20001],num[20001],v[20001],vs,n,in[20001];
char c;
int getv(int p){
	if(num[p]==0)return p;
	nth_element(v+first[p],v+first[p]+(num[p]+1)/2-1,v+first[p]+num[p]);
	return v[first[p]+(num[p]+1)/2-1]; 
}
void dfs(int p){
	for(int i=0;i<num[p];i++){
		int t=v[first[p]+i];
		if(num[t]!=0)dfs(t);
		v[first[p]+i]= getv(t);//跟新當前節點值 
	}
}
inline void scan(int &x){
	while(c=getchar(),c<'0'||c>'9');
	x=c-'0';
	while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';	
}
int main(){
	while(scanf("%d",&n)!=EOF){
		first[1]=1;
		vs=1;
		for(int i=1;i<=n;i++)in[i]=0;
		
		for(int i=1;i<=n;i++){
			scan(num[i]);//child個數,也是child所佔連續空間 
			for(int j=0;j<num[i];j++){
				scan(v[vs]);
				in[v[vs]]++;
				vs++;
			}
			first[i+1]=first[i]+num[i];//標記下一個節點child的存儲開始位置 
		}
		
		first[0]=0,num[0]=1;
		for(int i=1;i<=n;i++){if(in[i]==0){v[0]=i;break;}}
		dfs(0);	 
		printf("%d\n",v[0]);
	}
	return 0;	
}

4.3.8  HDU2616 Kill the monster
簡單的深搜+回溯
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
int n,m,bella[12],bellm[12],a[12],use[12],res;
void dfs(int p){
	if(p==n+1){
		int nowm=m;
		for(int i=1;i<=n;i++){
			if(nowm<=bellm[a[i]])nowm-=2*bella[a[i]];
			else nowm-=bella[a[i]];
			if(nowm<=0){
				res=min(res,i);
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(!use[i]){
			use[i]=1;
			a[p]=i;
			dfs(p+1);
			use[i]=0;	
		}	
	}
}
int main(){
	while(scanf("%d%d",&n,&m)!=EOF){
		for(int i=1;i<=n;i++)scanf("%d%d",&bella[i],&bellm[i]);
		memset(use,0,sizeof use);
		res=20;
		dfs(1);
		if(res!=20)printf("%d\n",res);
		else printf("-1\n");
	}
	return 0;	
}



發佈了91 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章