poj2531 DFS

本題題意:先給你說明有幾個點,然後給你幾個點的之間的距離,問將這些點分在兩邊,求點距離的最大值

dfs最怕的就是你的重複計算,一不小心把以前走過的路又走了一遍
例如本題卡我這麼久的T,我因爲是我剪的不夠好,我考慮到兩邊重複的情況,所有A那邊最少數量不能少於一半,不能其實AB邊發生了重複
例如A1,2 B 3 這種情況等價於 A 3 B 1,2
但我沒有寫好的地方是,這題的思想是組合,也就是**前面一步確定好狀態後不能回頭!!!**而我卻將它寫成了組合,導致自己寫出了A 1,2 B 3 然後有會再出現 A 2,1 B 3 的情況
其他沒啥好注意的了,只要不要在傳參的時候,傳錯就行啦
上代碼:
1.兩個數組

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[25][25];
int A[25],B[25],maxn = 0,n;
void DFS(int w,int nb ,int Vs,int na)
{
	if( na <= n/2) return;
	for (int i = w; i <= n; i++)//轉移 
	{
		int kk = Vs;
		if(A[i]!= 0 ) {
			for (int j = 1; j <= n; j++){
				if( A[j]!= 0 ) kk+=a[A[i]][A[j]];
			}
			for (int j = 1; j <= nb; j++){
					 kk-=a[A[i]][B[j]]; 
			}
			if(kk > maxn)  maxn = kk;
			if(kk > Vs){
				 B[nb+1] = A[i];
				 A[i] = 0;
				 DFS(i+1,nb+1,kk,na-1);//這步的  i+1 !!!!!!!
				 A[i] = B[nb+1];
				 B[nb+1] = 0;
			}
		}
	}
}
int main()
{
	scanf("%d",&n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			scanf("%d",&a[i][j]);
	}
	for (int i = 1; i <= n; i++)
	{
		A[i] = i;
	}
	DFS(1,0,0,n);
	cout<<maxn<<endl;
 } 

一維數組,其實保存到底這個數在左在右01判斷即可

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[25][25];
int A[25],maxn = 0,n;
void DFS(int w, int Vs,int na)
{
	//if( na <= n/2) return;
	for (int i = w; i <= n; i++)//轉移 
	{
		A[i] = 0;		
 		int kk = Vs;
			for (int j = 1; j <= n; j++){
				if( A[j]!= 0 ) kk+=a[i][j];
				else kk-=a[i][j];
			}
			if(kk > maxn)  maxn = kk;
			if(kk > Vs){
				 DFS(i+1,kk,na-1);
			}
		A[i] = 1;
	}
}
int main()
{
	scanf("%d",&n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			scanf("%d",&a[i][j]);
	}
	for (int i = 1; i <= n; i++)	A[i] = 1;
	DFS(1,0,n);
	cout<<maxn<<endl;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章