一道简单题题解(含题意)

文章讨论了一种数据结构问题,小X需要通过服务获取王爷的赏赐,每次服务可以在数字左侧或右侧添加数字。目标是找到使最终赏赐数值最大的方法。通过贪心策略,优先在左侧添加最大的数,然后递归处理剩余部分,最终得到最大数值。代码示例使用C++实现,强调了排序和避免高常数操作的重要性。
摘要由CSDN通过智能技术生成

写不动数据结构了,下午打打D班的模拟赛玩玩。

题面:

小X穿越了,发现自己成为了一个小人,正准备为一位清朝王爷服务。只要好好地服务,王爷就有赏。

一开始,小X的赏赐是 a 0 a_0 a0,满足 0 ≤ a 0 ≤ 9 0\le a_0\le 9 0a09

小X将为王爷服务 n n n 次,第 i i i 次他有两种方式为王爷服务:

为王爷整理胡子。王爷会在原有赏赐的数字左侧添加一位,添加的数字为 a i a_i ai ( 0 ≤ a i ≤ 9 ) (0 \le a_i \le 9) (0ai9)

给王爷唱歌。王爷会在原有赏赐的数字右侧添加一位,添加的数字为 a i a_i ai

小X想知道,他最终能获得的最多赏赐是多少。

输入格式

第一行一个整数 n n n,表示服务的次数。

第二行 n + 1 n+1 n+1 0 0 0 9 9 9 的整数,表示 a 0 , a 1 , a 2 , … , a n a_0,a_1,a_2,…,a_n a0,a1,a2,,an ( n ≤ 1 0 6 ) (n\le 10^6) (n106)

保证a中不全为0。

输出格式

一个数,表示小X取得的最多赏赐。

样例

input

6
0 1 2 3 2 6 4

output

6321024

简化题意:

给定原数位,按顺序给原数补位,可以选择补在前或者补在后,求最后的数的最大值。

思路

考虑贪心和分治。

越靠左的位置越大数就越大,所以考虑对放左侧贪心。

最大且最靠右的一定得放最左,那它后面的数只能放右。

就递归按照这种方法处理前面的数,最后按顺序把数放在右侧即可。

加排序复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

注:千万不要让solve()函数返回string然后在中途为了图方便用substr() 分割,常数太大,且单次分割复杂度 O ( n ) O(n) O(n),导致我挂了个点只有75分,用数组就好,数组常数小。

C o d e Code Code

struct node{
    int id,v;
    inline bool operator <(const node&w)const{
        if(v==w.v)return id>w.id;
        return v>w.v;
    }
}o[1000006];
int n,t=1,a[1000006];
void solve(int r){
    if(r<1)return;
    while(o[t].id>r)t++;
    int x=o[t].id;
    printf("%d",a[x]);
    solve(x-1);
    for(int i=x+1;i<=r;i++)printf("%d",a[i]);
}
int main(){
    n=read();
    for(int i=1;i<=n+1;i++){
        o[i]={i,a[i]=read()};
    }
    sort(o+1,o+2+n);
    solve(n+1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值