参考:https://blog.csdn.net/A_Bright_CH/article/details/83786942
本菜鸡参考上述链接算法,结果超时了,因而做了些改进,空间成本减少了一半以上。
改进点:在暴力穷举第m个数时,[max+1,sum+1],从大到小穷举,如果某个数满足2*sum+1<n,那比它小的数肯定也满足,这些都不会增加新的方案,所以不用再取了。
#include<iostream>
#include<math.h>
using namespace std;
int n, m;
int result = 0;
int flag;
int fun(int t, int sum, int max)
//t表示需要确定的第t个数,sum为总和,max为当前最大数
{
flag = 1;
if (t == m)
//确定第m个数的值
{
if (2 * sum + 1 < n)
//result+=0;
return 0;
else if (sum + max + 1 >= n) {
result += sum - max + 1;
return 1;
}
else {
result += 2 * sum + 2 - n;
return 1;
}
}
else {
for (int i = sum + 1; i >= max + 1 && flag == 1; i--) {
flag = fun(t + 1, sum + i, i);
}
//最新加入的数只能是[max+1,sum+1]
return 1;
}
}
int main()
{
//int n;
cin >> n;
m = floor(log2(n)) + 1;//m就是需要使用的最少个数
//cout<<m<<endl;
fun(1, 0, 0);//从第一个数开始确定
cout << m << " " << result << endl;
return 0;
}