洛谷1490 买蛋糕

参考: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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值