zoukankan      html  css  js  c++  java
  • [CF752D]Santa Claus and a Palindrome(优先队列,贪心乱搞)

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

    题意:给长度为k的n个字符串,每一个字符串有权值,求构造一个大回文串。使得权值最大。

    因为字符串长度都一样,所以想构成回文串,必须两两配对,在中间加或者不加一个本身就是回文的字符串。

    1.考虑非回文串的配对,把所有可以构成回文的非回文串凑起来,必须两两权值和>0才有意义。那么就扔到优先队列里配对。

    2.考虑回文串的配对,配对成功的话要看下是不是两个回文串都是>0,如果不是,要额外在一个vector里记下,方便后面用。

    3.这时候挑一个>0的,备选放在中间。

    比较上面的2.3,求最优。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 typedef pair<LL, LL> pll;
     6 const int maxn = 100100;
     7 int n, k, tmp;
     8 char s[maxn];
     9 vector<string> str, rev;
    10 map<string, priority_queue<LL> > wt;
    11 
    12 int main() {
    13   // freopen("in", "r", stdin);
    14   while(~scanf("%d%d",&n, &k)) {
    15     wt.clear(); str.clear(); rev.clear();
    16     for(int i = 0; i < n; i++) {
    17       scanf("%s %d", s, &tmp);
    18       str.push_back(s);
    19       rev.push_back(s);
    20       reverse(rev[i].begin(), rev[i].end());
    21       wt[s].push(tmp);
    22     }
    23     LL ret = 0;
    24     for(int i = 0; i < str.size(); i++) {
    25       if(str[i] != rev[i]) {
    26         while(wt[str[i]].size() > 0 && wt[rev[i]].size() > 0) {
    27           int x = wt[str[i]].top();
    28           wt[str[i]].pop();
    29           int y = wt[rev[i]].top();
    30           wt[rev[i]].pop();
    31           if(x + y > 0) ret += x + y;
    32           else {            
    33             if(x > 0) wt[str[i]].push(x);
    34             if(y > 0) wt[rev[i]].push(y);
    35             break;
    36           }
    37         }
    38       }
    39     }
    40     vector<pll> tmp;
    41     for(int i = 0; i < str.size(); i++) {
    42       if(str[i] == rev[i]) {
    43         while(wt[str[i]].size() > 1) {
    44           int x = wt[str[i]].top();
    45           wt[str[i]].pop();
    46           int y = wt[str[i]].top();
    47           wt[str[i]].pop();
    48           if(x + y > 0) {
    49             ret += x + y;
    50             if(x > 0 && y > 0) continue;
    51             if(x > y) swap(x, y);
    52             tmp.push_back(pll(x, y));
    53           }
    54           else {
    55             if(x > 0) wt[str[i]].push(x);
    56             if(y > 0) wt[str[i]].push(y);
    57             break;
    58           }
    59         }
    60       }
    61     }
    62     LL aa = maxn, bb;
    63     for(int i = 0; i < tmp.size(); i++) {
    64       if(tmp[i].first < aa) {
    65         aa = tmp[i].first;
    66         bb = tmp[i].second;
    67       }
    68       // cout << tmp[i].first << " " << tmp[i].second << endl;
    69     }
    70     LL qq = 0;
    71     for(int i = 0; i < str.size(); i++) {
    72       if(str[i] == rev[i]) {
    73         if(wt[str[i]].size() > 0) {
    74           if(wt[str[i]].top() > 0) {
    75             qq = max(qq, wt[str[i]].top());
    76           }
    77         }
    78       }
    79     }
    80     if(aa == maxn) cout << max(ret + qq, ret) << endl;
    81     else cout << max(max(ret, ret + qq), ret - LL(aa)) << endl;
    82   }
    83   return 0;
    84 }
  • 相关阅读:
    创建线程方法
    List 接口
    implements 的用法
    import和export 的使用方法
    js 实现 a == 'juejin' && a == 666 && a == 888
    position的属性运用
    css calc()函数 长度运算
    .net5一分钟入门
    css 如何让大小不同的图片表现一致,同时自适应呢?
    sqlserver isnull(),Count(),sum(),month(getdate()) 的用法
  • 原文地址:https://www.cnblogs.com/kirai/p/6248764.html
Copyright © 2011-2022 走看看