zoukankan      html  css  js  c++  java
  • UVA 10905 Children's Game

    UVA_10905

        我们不妨先定义一个大于号“》”:对于字符串a,b,如果有a》b就表示ab的字典序要大于ba的字典序。

        假设:如果有a》b,且b》c,那么就有a》c。

        如果这个假设满足,那么N个字符串就可以按》的关系排成一排,这时拼成的字符串就是字典序最大的(同时也是值最大的,因为最终拼成的字符串的长度是一定的,所以值的大小关系和字典序的大小关系是相同的)。

        下面用反证法证明为什么这样拼成的字符串的字典序一定是最大的:如果最终拼成的字符串不是这样的,那么就一定存在相邻的两个字符串a、b不满足a》b,那么我们可以交换a、b的顺序,这样得到的结果不会变得更差。于是我们不停的交换不满足a》b的两个相邻的a、b,直到变成N个字符串是按》的关系排成一排为止,这样得到的结果不会变得更差。因此,可以保证这样拼成的字符串字典序是最大的。

        当然,这样的贪心思路是依赖于上文中字体加粗的“假设”部分的。如果不能证明这个假设是正确的,那么就没办法说明这个贪心是正确的(比如如果存在a》b,b》c且c》a,那么对于acb来讲,到底是变成cab更好,还是变成abc更好呢?这恐怕就说不清了吧……)。但是我暂时没证明出“假设”的部分,稍后补上……

        *上述讨论默认N个字符串是不同的,如果有相同的字符串,处理和证明的过程也基本相同,所以就没再讨论有相同字符串的情况了。

    #include<stdio.h>
    #include<string.h>
    #include<string>
    #include<algorithm>
    #include<iostream>
    std::string a[110];
    bool cmp(std::string a, std::string b)
    {
        return (a + b).compare(b + a) > 0;
    }
    int main()
    {
        int N;
        while(scanf("%d", &N), N)
        {
            for(int i = 0; i < N; i ++) std::cin >> a[i];
            std::sort(a, a + N, cmp);
            for(int i = 0; i < N; i ++) std::cout << a[i];
            std::cout << std::endl;
        }
        return 0;
    }
  • 相关阅读:
    laravel 服务容器,容器概念
    初识swoole
    一个小demo---递归计算子类下的某个值的总和
    微信支付の退款申请
    Box/Spout处理excel和csv
    mysql 获取指定日期的周/月开始 和 周/月结束
    时间字段规定模式获取
    异步服务器之心跳检测
    larave -- leftJoin IFNULL 链表查询
    Mac版Navicat破解
  • 原文地址:https://www.cnblogs.com/staginner/p/2760486.html
Copyright © 2011-2022 走看看