找一个最大的数,这个数是由这个数等于所在的序列中的某三个数的和。
第一种方法,我是用深度优先搜索来做的,但是返回的结果是超时;但是现在还不知道这个程序为什么超时,希望路过的各位指出程序的不足之处。
#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)这个题目的其他方法。我想用深搜应该是可以的,但是还没能实现。