找一個最大的數,這個數是由這個數等於所在的序列中的某三個數的和。
第一種方法,我是用深度優先搜索來做的,但是返回的結果是超時;但是現在還不知道這個程序爲什麼超時,希望路過的各位指出程序的不足之處。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1002
int a[N];
int sum;
bool DFS(int sum,int i)
{
if(sum<0)return false;
else if(sum==0) return true;
else
{
if(i-1>=0&&DFS(sum-a[i-1],i-1))return true;
if(i-2>=0&&DFS(sum-a[i-2],i-2))return true;
}
return false;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
if(n<4)
{
printf("no solution\n");
continue;
}
else
{
bool flag = false;
int i;
for(i=n;i>=4;i--)
{
sum = i;
if(DFS(sum,i-1))
{
flag = true;
break;
}
}
if(flag)printf("%d\n",a[i-1]);
else printf("no solution\n");
}
}
return 0;
}
第二種解法是n^3log(n)時間複雜度,剛開始看這個題目的時候,想到的是這種方法,但是想一想可能超時,就沒有去嘗試。
#include<stdio.h>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
void serch(int *a,int n)
{
if(n<4)
{
printf("no solution\n");
return;
}
sort(a,a+n);
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
if(i!=j&&j!=k&&i!=k)
{
int ans =a[i]-a[j]-a[k];
if(ans!=a[i]&&ans!=a[j]&&ans!=a[k]&&binary_search(a,a+n,ans))
{
printf("%d\n",a[i]);
return ;
}
}
}
}
}
printf("no solution\n");
}
int main()
{
int a[1002];
int n;
while(scanf("%d",&n)!=EOF)
{
if(n<=0)break;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
serch(a,n);
}
return 0;
}
(1)爲什麼這樣做?第二種方法是暴力搜索,一般都能夠想到這種方法。由於可能出現負數,所以搜索是這樣寫的。還用到了binary_serch()這個函數。
(2)這個題目還有什麼改進的地方呢?改進的地方我想是三重for()循環降低爲二重for()循環。這樣能夠改進算法的時間複雜度。可以將一個序列中的所有兩個數的和保存起來,進行搜索,這樣可以降低時間複雜度到n^2log(n);但是在具體的操作的時候還是需要注意很多的細節的。??
(3)這個題目的其他方法。我想用深搜應該是可以的,但是還沒能實現。