洛谷解题报告--P1028 [NOIP2001 普及组] 数的计算

链接 数的计算

题目

我们要求找出具有下列性质数的个数(包含输入的正整数 \(n\))。

先输入一个正整数 \(n(n \le 1000)\),然后对此正整数按照如下方法进行处理:

  1. 不作任何处理;
  2. 在它的左边加上一个正整数,但该正整数不能超过原数的一半;
  3. 加上数后,继续按此规则进行处理,直到不能再加正整数为止。

输入

一个正整数\(n\)

输出

1 个整数,表示具有该性质数的个数。

样例

6

####
6

设一个数\(n\)具有该性质数的个数为\(f(n)\),那么\(f(n) = (\sum_{i=1}^{n/2}f(i)) + 1\)

拿样例来说,\(n=6\),具有该性质的数是

6
16
26 126
36 136

如果是数2,那么具有该性质的数是

2
12

如果忽略掉最后的数,那么\(26,126\)\(2,12\)是相同的。
同理,\(1\)\(3\)的性质数也是相同的,那么它们的总数和就是\(f(1)+f(2)+f(3)\),同时还需要加上数本身,所以还需要\(+1\)
依次类推,就可以得到上面的公式。

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <numeric>
#include <map>
#include <set>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int M = 1e4 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define pb(x) push_back(x)
#define bg begin()
#define ed end()
#define mp make_pair
#define mem(x, a) memset(x, a, sizeof(x));
#define endl '\n'
#define _for(i, a, b) for (int i = a; i < b; ++i)
#define _rep(i, a, b) for (int i = a; i <= b; ++i)

int f[1010];

void init() {
	f[1] = 1, f[2] = 2, f[3] = 2;
	_rep(i, 4, 1000) {
		_rep(j, 1, i / 2) {
			f[i] += f[j];
		}
		f[i]++;
	}
}

int main() {
	init();
	int n;
	cin >> n;
	cout << f[n];
	return 0;
}
posted @ 2021-02-14 15:34  sxhyyq  阅读(255)  评论(0编辑  收藏  举报