hpuoj-1048-QAQ的纸币问题(二)【思维】

题目链接:点击打开链接

1048: QAQ的纸币问题(二) [思维]

时间限制: 1 Sec   内存限制: 128 MB
提交: 18   解决: 7
[ 提交][ 状态][ 讨论版]

题目描述

这天无聊的QAQ又在研究纸币的组合问题,QAQ发现只需要 127 1、2、7三种面值就可以通过加法和减法组成 110 1−10的所有数字。如:
1=1 1=1
2=2 2=2
3=1+2 3=1+2
4=712 4=7−1−2
5=72 5=7−2
6=71 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想知道最少需要多少种不同的面值就可以构成从 1N 1−N的所有数字,由于 N N很大,就请了你这个BestCoder来帮他。
PS:构成每一个数字,同种面值最多使用一张。

输入

第一行输入一个整数 T T,代表有 T T组测试数据。

每组数据输入一个整数 N N,代表上面提到的信息。


注: 1<=T<=6666661<=N<=666666 1<=T<=666666,1<=N<=666666

输出

输出一个整数代表最后的结果。

样例输入

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值