Codeforces 633D Fibonacci-ish 暴力

题意:1000个元素,每个元素的大小-1e9<=a[i]<=1e9,然后让你重新安排这些元素的位置

获得最长的前缀斐波那契数列

分析:枚举第一个元素和第二个元素,因为在题目元素的范围内,最多形成长度为90的斐波那契数列

除非有全0的情况出现,这种情况会达到长度1000

所以这种情况特判一下(记录一下零元素的个数就行了)

然后枚举是n^2的

找元素是90,然后找的时候,我用的map来找

所以时间复杂度是略大是O(90n^2logn)

所以由于不可能每次都找到90,所以均摊比较小,这题时限是3s,我跑了2012ms

主要是我太弱(这是刚比完赛看题解写的)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const int N=1000000+5;
map<LL,int>mp;
LL a[1005];
int main()
{
    int n;
    LL res=0,mx=-1;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
       scanf("%I64d",&a[i]);
       mx=max(a[i],mx);
      if(a[i]==0)++res;
      mp[a[i]]++;
    }
    LL ans=2;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=n;++j)
        {
           if(j==i)continue;
           if(a[i]==0&&a[j]==0)continue;
           LL x=a[i],y=a[j],cnt=2;
           vector<LL>t;
           t.clear();
           t.push_back(x);
           t.push_back(y);
           mp[x]--;
           mp[y]--;
           while(x+y<=mx&&mp[x+y]>0)
           {
              LL tmp=x+y;
              mp[tmp]--;
              t.push_back(tmp);
              x=y;
              y=tmp;
              ++cnt;
           }
           for(int k=0;k<t.size();k++)
            mp[t[k]]++;
           ans=max(ans,cnt);
        }
    }
    printf("%I64d\n",max(ans,res));
    return 0;
}

然后后来我又写了一份,之所以用MAP找,是因为元素范围大

所以可以用排序hash,用lower_bound来找,这样复杂度其实和上面的复杂度原理上和上面一样

但是由于用数组实现,所肯定比STL要快,写成这样才跑了826ms

所以说能不用STL,还是不用吧

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const int N=1000000+5;
int a[1005],b[1005],sum[1005],pos[1005];
int main()
{
    int res=0,mx=-1,n,l=0;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
    {
        scanf("%d",&a[i]);
        mx=max(a[i],mx);
        if(a[i]==0)++res;
    }
    sort(a+1,a+1+n);
    b[++l]=a[1];
    for(int i=2; i<=n; ++i)
        if(a[i]!=a[i-1])b[++l]=a[i];
    for(int i=1; i<=n; ++i)
    {
        pos[i]=lower_bound(b+1,b+1+l,a[i])-b;
        ++sum[pos[i]];
    }
    int ans=2;
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
        {
            if(j==i)continue;
            if(a[i]==0&&a[j]==0)continue;
            int x=a[i],y=a[j],cnt=2;
            vector<int>t;
            t.clear();
            sum[pos[i]]--;
            sum[pos[j]]--;
            t.push_back(pos[i]);
            t.push_back(pos[j]);
            while(x+y<=mx)
            {
                int z=lower_bound(b+1,b+1+l,x+y)-b;
                if(z==l+1||b[z]!=x+y||!sum[z])break;
                sum[z]--;
                t.push_back(z);
                int tmp=x+y;
                x=y;
                y=tmp;
                ++cnt;
            }
            for(int k=0; k<t.size(); k++)
                sum[t[k]]++;
            ans=max(ans,cnt);
        }
    }
    printf("%d\n",max(ans,res));
    return 0;
}

时间: 2024-10-14 00:33:35

Codeforces 633D Fibonacci-ish 暴力的相关文章

Codeforces 126D Fibonacci Sums 求n由任意的Sum(fib)的方法数 dp

题目链接:点击打开链接 题意: 给定一个数n 问把这个数拆成多个不相同的fibonacci数 有多少种拆法 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<m

Codeforces 57C Array dp暴力找规律

题目链接:点击打开链接 先是计算非递增的方案, 若非递增的方案数为x, 则非递减的方案数也是x 答案就是 2*x - n 只需求得x即可. 可以先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元即可. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #def

Codeforces 57B Martian Architecture 暴力||线段树

题目链接:点击打开链接 题意:n长的序列(初始全为0) m个操作 k个查询 下面m个操作[l,r] h 代表 a[l] +=h; a[l+1] += h+i; a[l+i] += h+i;  l<=i<=r 然后问k个位置的和 因为k<=100 所以直接暴力也可以 ----------------------- 如果k<=100000 也是可以做的 只需要给区间记录一个标记lazy,表示从左端点开始 l, l+1, l+i ··· l+r 而向下更新时, 左区间则直接更新, 右区间

codeforces 724B Batch Sort(暴力-列交换一次每行交换一次)

题目链接:http://codeforces.com/problemset/problem/724/B 题目大意: 给出N*M矩阵,对于该矩阵有两种操作: (保证,每行输入的数是 1-m 之间的数且不重复) 1.交换两列,对于整个矩阵只能操作一次 2.每行交换两个数. 交换后是否可以使每行都是1-m 数字递增. 解题思路: 1.得到矩阵后先判断,是否每行可以交换两个数可以得到递增的矩阵,如果可以则输出“YES”. 2.暴力交换两列,交换两列后,判断每行是否可以交换两个数得到递增的矩阵,如果可以则

[codeforces 200 A Cinema]暴力,优化

题意大致是这样的:有一个有n行.每行m个格子的矩形,每次往指定格子里填石子,如果指定格子里已经填过了,则找到与其曼哈顿距离最小的格子,然后填进去,有多个的时候依次按x.y从小到大排序然后取最小的.输出每次填的格子的坐标. 思路:这道题出自Codeforces Round #126 (Div. 2)是个暴力优化的题.如果指定格子未填,则填到里面.否则枚举曼哈顿距离,然后枚举格子找答案.裸的暴力太慢了,主要是因为每次曼哈顿距离都是从1开始搜索,如果每次指定的坐标都是同一个,则做了大量的重复工作.不妨

codeforces 897A Scarborough Fair 暴力签到

codeforces 897A Scarborough Fair 题目链接: http://codeforces.com/problemset/problem/897/A 思路: 暴力大法好 代码: #include <iostream> #include <stdio.h> #include <string.h> using namespace std; typedef long long ll; int n,m; string s; int main() { ios

CodeForces 589B Layer Cake (暴力)

题意:给定 n 个矩形是a*b的,问你把每一块都分成一样的,然后全放一块,高度都是1,体积最大是多少. 析:这个题,当时并没有完全读懂题意,而且也不怎么会做,没想到就是一个暴力,先排序,先从大的开始选,如果大,那么数量少,如果小,数量就多, 用一个multiset来排序,这样时间复杂度会低一点,每一个都算一下比它的大矩阵的数量,然后算体积,不断更新,最大值. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #i

CodeForces 398A Cards 贪心 暴力 瞎搞

搞了一晚上了快,各种YY乱搞啊,终于过了,一开始YY的都是错的,觉得 这道题目a,b的范围都是10^5,那就暴力枚举b被分成了几份,然后再继续YY,只用一个o去分隔x,这样最后剩下的o再集中在一起,也就是x的份数总是比o的份数多一份,也就是尽可能把x分开,尽可能把o集中在一块,前面都把x分开了,一个o分开两份x,后面还能有一大堆的o在一起,这样就满足了,然后又出错了,因为分成几份,有余数的,比如b = 6,你要分成4份,我以开始是分成 1  1  1  3这样子,这样不行,应该分成 1 1 2

Codeforces 831C--Jury Marks (暴力)

题目链接:http://codeforces.com/problemset/problem/831/C 题意:有一位参赛选手,我们不知道他初始或最后的成绩,但是知道k次评审所加(减)的分数,以及n个在这过程中的他的分数.问这名选手初始分有几种情况. 思路:一开始考虑先求出评审分的前缀和,对过程分减去前缀和就能得到的初始分数,求出所有的初始分数情况,用map记录每个初始分重复的次数,重复次数==n 的即为正确的初始分. 然而这么做是WA了的. 分析第一个样例: 4 1-5 5 0 2010 如果按