本題題意:先給你說明有幾個點,然後給你幾個點的之間的距離,問將這些點分在兩邊,求點距離的最大值
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;
}