zoukankan      html  css  js  c++  java
  • Codeforces Round #514 (Div. 2) C. Sequence Transformation(递归)

    C. Sequence Transformation

    题目链接:https://codeforces.com/contest/1059/problem/C

    题意:

    现在有1~n共n个数,然后执行下面操作:

    1.求出余下数的gcd,然后将gcd加入答案队列;

    2.从中任意删除一个数,如果余下数的个数大于0,回到步骤1。

    问答案队列字典序最大是什么。

    题解:

    这明明是递归在做极其方便,我偏偏用for循环来搞,加各种判断...

    首先对于1,2,3...n来说,我们每次删去一个数时,肯定首先删去的是奇数嘛,奇数有(n+1)/2个,也就是前(n+1)/2都为1。

    现在考虑如果不选奇数位置,答案有没有可能更优。更优的话考虑我们留下3,6,9....这样的(之前相当于我们留下2,4,6...这样的),即3的倍数。

    前n个有n/3个3的倍数,有n/2个2的倍数,容易验证当n>3时,2的倍数的个数是大于3的倍数的个数的。同理,可以验证留下4,5的倍数...

    会发现,当n>3时,2的倍数的个数是最多的,也就是我们删去的数个数是最少的,要求字典序最大,我们就留2的倍数就行了。对于n<=3,答案显而易见。

    之后的式子就是2,4,.....2*k,全为2的倍数,这个时候提取2出来,就变为2*(1+2+...+k),又回到刚才那个问题了。所以直接递归求解就是了。

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n;
    vector <int> ans;
    void solve(int x,int y){
        if(x==1){
            ans.push_back(y);return ;
        }
        if(x==2){
            ans.push_back(y);ans.push_back(2*y);return ;
        }
        if(x==3){
            ans.push_back(y);ans.push_back(y);ans.push_back(3*y);return ;
        }
        int tmp=x;
        for(int i=1;i<=x;i+=2) ans.push_back(y),tmp--;
        solve(tmp,2*y);
    }
    int main(){
        cin>>n;
        solve(n,1);
        for(auto v:ans) cout<< v<<" ";
        return 0;
    }
  • 相关阅读:
    Element Form表单验证
    layui table中记住当前页
    Mysql定时任务
    Mysql存储过程
    StringRedisTemplate与redistemplate
    vue路由传值
    背景色渐变(兼容各浏览器)
    用onclick点击框架跳转
    美化滚动条
    图片无缝滚动
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10398373.html
Copyright © 2011-2022 走看看