HDU-5703 Desert 水题

HDU-5703 Desert 水题

题目:

Problem Description

A tourist gets lost in the desert with n liters of water. He drinks positive integer units of water each day.

Write a program to calculate how many different ways the tourist can drink up the water.

Input

The first line contains the number of test cases T(T≤10).
Next T lines contain the number n(1≤n≤1000000) for each test case.

Output

Output consists of T lines.
Each line contains the binary number which represents number of different ways to finish up the water specified in the test case.

Sample Input

1
3

Sample Output

100

Hint

3 liters of water can be comsumed in four different ways show in the following.

  1. 1 1 1
  2. 1 2
  3. 2 1
  4. 3

If we write 4 in binary, it’s 100.

题目大意:

给你T个正整数n,问你将每个数拆分为若干个正整数各自有多少种方案。

题目解析:

首先,我们很容易想到这是一道存在递推关系的题目,递推方程为:
f ( n ) = ∑ i = 0 n − 1 f ( i ) f(n)=\sum_{i=0}^{n-1} f(i) f(n)=i=0n1f(i)

具体解释就是,我在最后一天喝k个单位的水,那么就意味着我们在前面几天共喝了n-k个单位的水,那么最后f(n)的方案总数,实际就是前几天喝k个单位(0<=k<=n-1)的水的方案数之和。

有了这个想法以后,我们就开始考虑,这里直接算的话复杂会达到O(n^2),而n最大可达1e6,肯定TLE。那么能不能想办法优化呢?当然可以,只要我们在递推的过程中记录下到当前位置的方案数总和,即sum(f(i))) 0<=i<=n即可。这样,我们可以用一个sum直接边走边求值,复杂度降为O(n)。但是这样又有了另一个问题——溢出。没做题目之前,我们凭感觉都能知道,最后n=1e6的时候,肯定是会溢出的。那怎么办呢?开大数吗?其实根本不需要。

在递推的过程中,我们可以写出如下代码:

	cnt[0]=1,sm=1;
	for(int i=1;i<=n;i++){
		cnt[i]=sm;
		sm+=cnt[i]; //这里的cnt[i]其实是等于sm的,所以其实这里就是sm*=2
	}

这样子一来,就更加清晰了,cnt[i]实际上就是2^(i-1)。而结果要的恰恰是二进制数,所以我们只要输出一个1,再输出(i-1)个0就可以了。
AC代码如下:

#include <cstdio>
using namespace std;
int main()
{
    int t,n;
    scanf("%d",&t);
    for(int i=0;i<t;i++){
        scanf("%d",&n);
        printf("1");
        for(int j=1;j<n;j++)
            printf("0");
        printf("\n");
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值