• 【codeforces 752D】Santa Claus and a Palindrome


    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Santa Claus likes palindromes very much. There was his birthday recently. k of his friends came to him to congratulate him, and each of them presented to him a string si having the same length n. We denote the beauty of the i-th string by ai. It can happen that ai is negative — that means that Santa doesn’t find this string beautiful at all.

    Santa Claus is crazy about palindromes. He is thinking about the following question: what is the maximum possible total beauty of a palindrome which can be obtained by concatenating some (possibly all) of the strings he has? Each present can be used at most once. Note that all strings have the same length n.

    Recall that a palindrome is a string that doesn’t change after one reverses it.

    Since the empty string is a palindrome too, the answer can’t be negative. Even if all ai’s are negative, Santa can obtain the empty string.

    Input
    The first line contains two positive integers k and n divided by space and denoting the number of Santa friends and the length of every string they’ve presented, respectively (1 ≤ k, n ≤ 100 000; n·k  ≤ 100 000).

    k lines follow. The i-th of them contains the string si and its beauty ai ( - 10 000 ≤ ai ≤ 10 000). The string consists of n lowercase English letters, and its beauty is integer. Some of strings may coincide. Also, equal strings can have different beauties.

    Output
    In the only line print the required maximum possible beauty.

    Examples
    input
    7 3
    abb 2
    aaa -3
    bba -1
    zyz -4
    abb 5
    aaa 7
    xyx 4
    output
    12
    input
    3 1
    a 1
    a 2
    a 3
    output
    6
    input
    2 5
    abcde 10000
    abcde 10000
    output
    0
    Note
    In the first example Santa can obtain abbaaaxyxaaabba by concatenating strings 5, 2, 7, 6 and 3 (in this order).

    【题目链接】:http://codeforces.com/contest/752/problem/D

    【题解】

    因为是由一个个字符串拼接起来的;
    所以如果s本身不是回文串的话;
    必须有一个s的倒序字符串和其对应;
    这样才能放在左边和右边形成回文串的一个部分;
    所以用一个map存同一个字符串有哪些数值ai;
    并把这些ai按照降序排;
    如果某个字符串s本身不是回文串->则只能放在最后整个回文串的左边和右边;
    所以要看一下s倒序后的字符串存不存在;如果不存在;则这个字符串最后不能加入到最后的回文串中;
    否则
    可以加入;
    加入的话,s和s的倒序的都取ai数值大的选就好(贪心);
    累加答案一下就可以了;
    s本身是回文串的有些特殊;
    需要考虑这个s是放在中间的位置还是放在左边和右边;
    左边和右边的直接每两个选一组就好;
    中间的那个需要在剩余的字符串中选;
    或者每两个中出现了有一个为负的;但是它们的和仍旧大于0
    则我们可以尝试只选那个正的(把它放在最中间)。以让其更优;
    所以原则就是先找左边和右边配对的;
    然后看看能不能找到一个放在最中间;

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int MAXN = 1e5+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int k,n,extra;
    LL ans = 0,ans1;
    map <string,vector <int> > dic;
    
    bool cmp(int a,int b)
    {
        return a>b;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(k);rei(n);
        string s;int x;
        rep1(i,1,k)
        {
            cin >> s >> x;
            dic[s].pb(x);
        }
        for (auto &p :dic)
        {
            auto& x = p.fi;
            auto& v = p.se;
            sort(v.begin(),v.end(),cmp);
            int len = v.size();
            auto re = x;
            reverse(re.begin(),re.end());
            if (re==x)
            {
                int i;
                for (i = 0;i+1<=len-1 && v[i]+v[i+1]>=0;i+=2)
                {
                    ans+=v[i]+v[i+1];
                    extra = max(extra,-min(v[i],v[i+1]));
                }
                for (;i <= len-1;i++)
                    extra = max(extra,v[i]);
            }
            else
            {
                if (dic[re].empty())
                    continue;
                auto& vv = dic[re];
                int len2 = vv.size();
                sort(vv.begin(),vv.end(),cmp);
                len = min(len,len2);
                rep1(i,0,len-1)
                    if (v[i]+vv[i]>0)
                        ans1+=(v[i]+vv[i]);
            }
        }
        cout << ans1/2+ans+extra;
        return 0;
    }
  • 相关阅读:
    【自然框架】之通用权限(七):权限到按钮
    伯伯2008年终总结[ 旅游 | 电影 | 文章 | C# | Javascript | CSS ]
    C# 用delegate实现AOP事务[C# | AOP | delegate]
    IHttpHandler中使用Session实现原理[ASP.NET | IHttpHandler |IRequiresSessionState]
    C# 视频监控系列(4):客户端——音频接收和截图
    控制随机抽中几率 [ C# | Random ]
    “LINQ已死”论 为言论1 致歉 [Java | .Net | 致歉 ]
    C# 视频监控系列(14):总结贴——VC++代码转成C#小结
    ^全^ 获取SQL SERVER2000/2005、MySql、Oracle元数据的SQL语句 [SQL语句来自CodeSmith]
    C# 视频监控系列(15):总结贴——可能用到的C# WinForm技术小结
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626765.html
Copyright © 2020-2023  润新知