题目链接:点击打开链接
1048: QAQ的纸币问题(二) [思维]
时间限制: 1 Sec 内存限制: 128 MB提交: 18 解决: 7
[ 提交][ 状态][ 讨论版]
题目描述
这天无聊的QAQ又在研究纸币的组合问题,QAQ发现只需要
1、2、7
1、2、7三种面值就可以通过加法和减法组成
1−10
1−10的所有数字。如:
1=1 1=1
2=2 2=2
3=1+2 3=1+2
4=7−1−2 4=7−1−2
5=7−2 5=7−2
6=7−1 6=7−1
7=7 7=7
8=1+7 8=1+7
9=2+7 9=2+7
10=1+2+7 10=1+2+7
QAQ想知道最少需要多少种不同的面值就可以构成从 1−N 1−N的所有数字,由于 N N很大,就请了你这个BestCoder来帮他。
PS:构成每一个数字,同种面值最多使用一张。
1=1 1=1
2=2 2=2
3=1+2 3=1+2
4=7−1−2 4=7−1−2
5=7−2 5=7−2
6=7−1 6=7−1
7=7 7=7
8=1+7 8=1+7
9=2+7 9=2+7
10=1+2+7 10=1+2+7
QAQ想知道最少需要多少种不同的面值就可以构成从 1−N 1−N的所有数字,由于 N N很大,就请了你这个BestCoder来帮他。
PS:构成每一个数字,同种面值最多使用一张。
输入
第一行输入一个整数
T
T,代表有
T
T组测试数据。
每组数据输入一个整数 N N,代表上面提到的信息。
输出
输出一个整数代表最后的结果。
样例输入
3
1
10
666666
样例输出
1
3
13
思路:
还可以增加难度的 —— 输出任意一种合法的选择方案。
如果理解了下面的过程,也是很简单的。
考虑一个最优策略:
第一次选择1,可以构造出数字1。
第二次选择3,可以构造数1~4所有数字。
第三次选择5,可以构造出1~9所有数字。
第四次选择10,可以构造出1~19所有数字。
……
发现:
选择 i 张纸币构造的最优解 = 选择 i - 1 张纸币构造的最优解的 2 倍 + 1。
预处理一下结果,每次查询时间复杂度 O(1)。预处理时间复杂度是 O(666666*2)。
心细的同学会发现选择的纸币也是有规律的
1,3,5,10,20,40,80,160,320,640......
所以说输出任意一种合法方案,也是很简单的。
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int sum=0,ans=0;
while(sum<n)
{
sum=sum+sum*2+1;
ans++;
}
printf("%d\n",ans);
}
return 0;
}