F(k)<(维护+枚举)\(找规律+递推+枚举)>

原创 2016年05月30日 21:26:21

题意

 小明有一个不降序列(f(1),f(2),f(3),……),f(k)代表在这个序列中大小是k的有f(k)个。我们规定f(n)的前12项如下图。

n 1 2 3 4 5 6 7 8 9 10 11 12

f(n) 1 2 2 3 3 4 4 4 5 5 5 6

现在给你一个n,你知道f(n)是多少吗?
多组测试数据
每组一个n(1<=n<=2000,000,000)。
###法一:正常情况下想的到。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const long long maxn=20000000;
int f[maxn];
int main ()
{
    int nn,i;
    long long j;
    f[1]=1;
    f[2]=2;
    f[3]=2;
    j=3;
    for(i=3;j<=maxn-3;i++)
    {
        nn=f[i];
        while(nn--&&j<=maxn)
        {
            f[++j]=i;
        }
    }
    int n;
    while(~scanf("%d",&n))
    {
        int ans=0,i;
        for(i=1;ans<n;i++)
        {
            ans+=f[i];
        }
        printf("%d\n",i-1);
    }
    return 0;
}

法二:正常情况下想不到

因为n的最大范围是20亿,显然不能数组保存,而且时间也不允许,也很难发现什么规律。我们可以换个角度,既然要找的是f[n]的值,那么我们把f[x]=i时的最大x记录为 d[i] = x;
d[1] = 1
d[2] = 3
d[3] = 5
d[4] = 8
d[5] = 11

仔细推敲不难发现规律
从3起,d[i] = d[i-1] + find(i); find(i) = min(k) 当d[k]>=i时
find(i)也就是d数组中大于等于i的一项的最小值的下标。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn=680000;
LL fuck[maxn];
int i;
int Find(int l,int r,int key)
{
    int mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if(fuck[mid]<key)
            l=mid+1;
        else
            r=mid;
    }
    return l;
}
void init()
{
    fuck[1]=1;fuck[2]=3;
    for(i=3;i<=673365;i++){
        fuck[i]=fuck[i-1]+Find(1,i-1,i);
    }

}
int main ()
{
    int n;init();
    while(~scanf("%d",&n))
        printf("%d\n",Find(1,i,n));
    return 0;
}

STL的魅力

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn=680000;
LL fuck[maxn];
int i;
void init()
{
    fuck[1]=1;fuck[2]=3;
    for(i=3;i<=673365;i++){
        fuck[i]=fuck[i-1]+(lower_bound(fuck+1, fuck+i-1,i)-fuck);
    }

}
int main ()
{
    int n;init();
    while(~scanf("%d",&n))
        printf("%ld\n",(lower_bound(fuck+1, fuck+i,n)-fuck));
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

UVa11464偶数矩阵(部分枚举+递推)

题意:有一个n*n的01矩阵,任务是把尽可能少的0变成1,使得每个元素的上、下、左、右元素之和为偶数。(n 0 0 0          0 1 0 1 0 0  ----->  1 0 1     .....

POJ 1753 Flip Game(bfs枚举+递推)

题目地址:http://poj.org/problem?id=1753

ACM 算法竞赛 八大基础算法 模拟法 字符串 递归分治 排序 枚举 贪心 递推

八大基础算法思想的总结

Matrix67的非常男女计划 (递推??枚举!!)

【问题描述】   Matrix67已经当过多次“媒人”了。他因此获得了许多经验。例如,距Matrix67观察,身高相近的人似乎比较合得来。   Matrix67在学校策划了一次大型的“非常男女”配对...

hrbust 1699 矩阵游戏【枚举找规律】

矩阵游戏 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 25(10 users) Total Accepted...

hdu 5504(枚举+找规律)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5504 官方题解: 注意先特判0 的情况:如果读入的数据有0 ,那么去掉所有的0 且最后答案和0 取...

Codeforces Round #365 (Div. 2) -- B. Mishka and trip (找规律枚举)

B. Mishka and trip time limit per test 1 second memory limit per test 256 megabytes input...

c8051f320_USB枚举过程.usb

  • 2013-09-23 20:12
  • 6.31MB
  • 下载

CodeForces 558C Amr and Chemistry (位运算,数论,规律,枚举)

Codeforces 558C 题意:给n个数字,对每个数字可以进行两种操作:num*2与num/2(向下取整),求:让n个数相等最少需要操作多少次。 分析: 计算每个数的二进制公共前缀. 枚...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)