Codeforces Round #514 (Div. 2) C. Sequence Transformation(递归)
2024-08-25 20:25:05
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==){
ans.push_back(y);return ;
}
if(x==){
ans.push_back(y);ans.push_back(*y);return ;
}
if(x==){
ans.push_back(y);ans.push_back(y);ans.push_back(*y);return ;
}
int tmp=x;
for(int i=;i<=x;i+=) ans.push_back(y),tmp--;
solve(tmp,*y);
}
int main(){
cin>>n;
solve(n,);
for(auto v:ans) cout<< v<<" ";
return ;
}
最新文章
- HDU 5055 Bob and math problem(简单贪心)
- 作业七:团队项目——Alpha版本冲刺阶段-14
- initializer for conditional binding must have optional type not AVAudioPlayer
- JDBC 事务控制
- RemixOS Player 让用户在 Windows 上运行 Android App
- MVC 5显示、创建、编辑、删除等功能实练
- 201521123095 《Java程序设计》第2周学习总结
- linq 在查询表达式中处理 null 值
- javaScript drag对象进行拖拽使用详解
- Vue技术内幕 出去看看吧
- mysql练习----More JOIN operations
- (最小生成树) codeVs 1231 最优布线问题
- Unity C#图片转换二进制流、字符串互转
- Python中单线程、多线程和多进程的效率对比实验
- Oracle.数据的增删改、表操作(创建,修改,删除)、数据类型
- 【项目 &#183; Wonderland】UML设计
- Android DrawLayout + ListView 的使用(一)
- TCP-IP详解:Nagle算法
- MySQL Desc指令相关
- PowerDesigner教程系列