• 1038 Recover the Smallest Number


    题目描述
    解题思路:具体看y总描述,(偏序关系证明)还是有点略懵。
    具体贪心证明:每个字符串要满足<关系,这个<关系是自己人为定义的。
    具体关系如下:若a<=b 等价于 ab<=ba。 其中ab表示拼接。
    有了这个关系之后,使用sort排序,从低到高进行拼接就可以了。
    证明为什么这么拼接可以是最优的
    假设现在最优解序列为 a 1 a 2 a 3 a i a i + 1 a n a_1a_2a_3a_ia_{i+1}a_n a1a2a3aiai+1an。使用反证法,如果不满足每个字符串都是我们定义的<关系,则必然存在一个 a i > a i + 1 a_i > a_{i+1} ai>ai+1,则等效于 a i a i + 1 > a i + 1 a i a_ia_{i+1} > a_{i+1}a_{i} aiai+1>ai+1ai,那我们完全可以将 a i 与 a i + 1 a_i与a_{i+1} aiai+1进行位置互换变为 a 1 a 2 a 3 a i + 1 a i a n a_1a_2a_3a_{i+1}a_{i}a_n a1a2a3ai+1aian,其余不变,中间这段变小了,则原序列就不是最优解,假设矛盾。

    至于为什么不能直接对字符串字典序排序,而需要定义新的比较方式。那是因为我们用下面的做法,但是无法使用反证法证明出这样贪心是最优的。因为在反证法过程中: a i > a i + 1 a_i > a_{i+1} ai>ai+1你无法保证交换完顺序之后,拼接的时候 a i a i + 1 a_ia_{i+1} aiai+1> a i + 1 a i a_{i+1}a_i ai+1ai,如:8677 867 8677867 < 8678677

    #include
    #include
    #include
    using namespace std;
    const int N = 1e5+10;
    string s[N];
    int cmp(string a,string b){
        return a+b < b+a;
    }
    int main(){       
        int n;
        cin>>n;
        for(int i = 0;i < n;i++) cin>>s[i];
        sort(s,s+n,cmp);
        string res = "";
        for(int i = 0;i < n;i++) res += s[i];
        int i = 0;
        while(i + 1 <= res.length()-1 && res[i] == '0') i++;
        cout<<res.substr(i);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    Java-IO流学习
    微信小程序--》从模块小程序项目案例23.10.09
    Nginx详细入门--配置理解,反向代理负载均衡,限流,高可用,防盗链等
    LeetCode Cookbook 双指针 上篇 难点
    day14I102.二叉树的层序遍历
    ES6及其后续版本的新特性的理解
    redis数据导入导出 - AOF方式
    C语言 一、二维数组
    Three.js中加载和渲染3D Tiles
    golang——工程组件logrus日志记录框架(结构化记录,支持文件切割,hook)
  • 原文地址:https://blog.csdn.net/weixin_49801142/article/details/126101006