买蛋糕
题目描述
野猫过生日,大家当然会送礼物了(咳咳,没送礼物的同志注意了哈!!),由于不知道送什么好,又考虑到实用性等其他问题,大家决定合伙给野猫买一个生日蛋糕。大家不知道最后要买的蛋糕的准确价格,而只会给蛋糕估价,即要买一个不超过多少钱的蛋糕。众 OIer 借此发挥:能否用最少的钱币数去凑成估价范围内的所有价值,使得不管蛋糕价值多少,都不用找钱……
现在问题由此引出:对于一个给定的 \(n\),能否用最少的不等的正整数去组成 \(n\) 以内(包括 \(n\))的所有的正整数呢?如果能,最少需要多少个正整数,用最少个数又有多少不同的组成方法呢?
输入格式
只有一行包含一个整数 \(n\ (1\le n\le 1000)\)。
输出格式
一行两个数,第一个数是最少需要多少个数,第二个数是用最少个数的组成方案个数。两个答案用空格分隔。
6
3 2
提示
最少用三个数,有两种方法,分别是:\(1,2,3\) 和 \(1,2,4\)。
- 对于 \(1,2,3\) 有 \(1,2,3\),\(1+3\),\(2+3\),\(1+2+3\);
- 对于 \(1,2,4\) 有 \(1\),\(2\),\(1+2\),\(4\),\(1+4\),\(2+4\)。
#include<bits/stdc++.h>
using namespace std;
int n;
int ans;
int ans1;
void dfs(int last,int sum,int cnt)//每个数的取值范围:[last+1,sum+1],上一个数是last,可以凑出1~sum的值,当前是第cnt个数
{
//值要<=sum+1,否则凑不出sum+1,要>=last+1否则个数就会超过ans
//求出后就可以凑出1~sum+x的数了
//在最后一个数时,数的左边界应该是max(n-sum,last+1)因为还要确保达到n
if(cnt == ans)
{
if(sum+sum+1>=n)//当前在最后一个数,sum+此数最大值可以到达n,才去统计答案
{
ans1+=sum+1-max(n-sum,last+1)+1;//统计答案
}
return ;
}
for(int i=last+1;i<=sum+1;i++)
{
dfs(i,sum+i,cnt+1);
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
for(int x=1;x<=n;x*=2,ans++);
cout<<ans<<' ';
dfs(0,0,1);
cout<<ans1<<'\n';
return 0;
}
作者:
ltl0825
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号