在网上看到的一个题目,从N个数字(N较大)从取出随意m个数字(m不定)相加,得到最接近一个常数c的组合,网上有不少类似算法,但多为int类型数据,这个为double型,而且N都较小,或者要求相等,最优解的例子较少,所以写了一个,时间复杂度为O(2^n),所以在数字较大的时候,结果没法验证,在数字较小的情况,结果完全正确而且必定是最优解
/**********************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;
void QuickSort(double e[], int first, int end);
void Compare(double e[],int s,int n);
const int N=99;
const double mubiao=412645.6;
double temp[N]={0};
double tar[N]={0};
double tempnum=0;
double tarnum=412645.6;
int main()
{
int i=0;
int x=0;
int y=0;
double sum1=0;
double sum2=0;
double s[N];
ifstream in;
in.open("shuzi.txt");
if (!in.is_open())
{
cout<<"Can't open the file";
exit(EXIT_FAILURE);
}
in>>s[i];
while(in.good())
{
i++;
in>>s[i];
}
QuickSort(s,0,N-1);
while (sum1<mubiao)
{
sum1=sum1+s[x];
x++;
}
while(sum2<mubiao)
{
sum2=sum2+s[N-1-y];
y++;
}
for (int k=y;k<x;k++)
{
Compare(s,k,N);
}
cout<<"The best group is:"<<endl;
for (int j=0;j<N;j++)
{
cout<<tar[j]<<endl;
}
system("Pause");
}
void QuickSort(double e[], int first, int end)
{
int i=first,j=end;
double temp=e[first];
while(i<j)
{
while(i<j && e[j]>=temp)
j--;
e[i]=e[j];
while(i<j && e[i]<=temp)
i++;
e[j]=e[i];
}
e[i]=temp;
if(first<i-1)
QuickSort(e,first,i-1);
if(end>i+1)
QuickSort(e,i+1,end);
}
void Compare(double e[],int s,int n)
{
for(int i=n;i>=s;i--)
{
temp[s]=e[i];
if (s>1)
{
Compare(e,s-1,n-1);
}
else
{
for (int j=0;j<N;j++)
{
tempnum=tempnum+temp[j];
}
if (abs(mubiao-tempnum)<tarnum)
{
tarnum=abs(mubiao-tempnum);
tempnum=0;
for (int j=0;j<N;j++)
{
tar[j]=temp[j];
}
}
else
{
tempnum=0;
}
}
}
}