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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

贪心、回溯、穷举、分治、递归

常用算法[1] 贪心算法[2] 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所...
  • wanghhm2014
  • wanghhm2014
  • 2017年09月25日 12:02
  • 127

五大基础算法(枚举、递归、分治、贪心、模拟)

一、枚举法 枚举法,本质上就是搜索算法。 基本思想: 枚举也称作穷举,指的是从问题所有可能的解的集合中一一枚举各元素。 用题目中给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立。即为其解。...
  • Linoi
  • Linoi
  • 2013年12月18日 13:09
  • 6121

【topcoder第二弹】SRM 526 Div.1 DucksAlignment

Problem Statement      Mr. Dengklek has a rectangular farm conveniently divided into a grid of uni...
  • fghdvbgt
  • fghdvbgt
  • 2014年07月13日 15:51
  • 608

C++中枚举的简单使用

•C++的枚举不再是普通的整数类型,而是一种独立的类型,这个体现了C++强类型的特征 // 枚举 #include using namespace std; // //英雄的...
  • love9099
  • love9099
  • 2015年01月10日 16:13
  • 733

USB 枚举过程

HS/FS connection detect(注意,这里的connection指的是检测到attach/termination等开始的connection,从软件层面看来是link statu...
  • zifeiyu1988
  • zifeiyu1988
  • 2017年02月22日 19:44
  • 211

POJ 2559(第三届河南省程序设计大赛F题(单调栈应用))

Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: ...
  • Aiwen1413
  • Aiwen1413
  • 2017年03月19日 14:24
  • 294

枚举解决自定义异常

自定义异常: public interface ExceptionEnums { public int getCode(); public String getMessage(); }...
  • sunhuwh
  • sunhuwh
  • 2015年02月06日 00:37
  • 2107

一个用枚举类型定义错误码的Demo

/** * Created by gfj43958 on 2017/1/6. */ public enum WrapperEnumError { //网络超时 SOCKET_T...
  • GFJ0814
  • GFJ0814
  • 2017年01月16日 10:39
  • 1290

在PowerShell中使用枚举类型

我们都知道PowerShell是基于NET Framework库的,自从PowerShell开始支持Class关键字后,我们也可以在PowerShell使用Enum枚举...
  • itanders
  • itanders
  • 2016年05月03日 23:44
  • 480

Java集合框架:EnumMap

EnumMap的key不允许为null,value可以为null,按照key在enum中的顺序进行保存,非线程安全。可以用工具类Collections进行包装成线程安全的: ``` Map m = C...
  • u013256816
  • u013256816
  • 2016年03月17日 19:59
  • 4866
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:F(k)<(维护+枚举)\(找规律+递推+枚举)>
举报原因:
原因补充:

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