首页 > 其他 > 详细

Codeforces 1526D - Kill Anton(逆序数)

时间:2021-05-30 15:41:24      阅读:38      评论:0      收藏:0      [点我收藏+]

题目链接

题目大意

??给你一个字符串s,让你用s中的字符构造t,使得t通过交换相邻的字符变成s的最小交换次数最大。

解题思路

??结论是相同的字符都放一起结果不会更差(不会证)。然后因为只有4个字符,所以可以用全排列枚举所有方案,然后求逆序数。因为就只有4个字符,且都是相连的,所以可以先求出每个字符换到其他字符前面需要的交换次数,这样就能O(n)求逆序数了。

代码

const int maxn = 1e5+10;
map<char, int> mp = {{‘A‘, 0}, {‘O‘, 1}, {‘T‘, 2}, {‘N‘, 3}};
ll c[5][5], c2[5];
int main(void) {
    IOS; int __; cin >> __;
    while(__--) {
        string a = "AOTN";
        sort(a.begin(), a.end());
        string s; cin >> s;
        int n = s.size();
        for (int i = 0; i<n; ++i) ++c2[mp[s[i]]];
        for (int i = 0; i<4; ++i) {
            int cnt = 0;
            for (int j = 0; j<n; ++j) {
                c[i][mp[s[j]]] += cnt; 
                if (i==mp[s[j]]) ++cnt;
            }
        }
        ll maxx = 0; string ans = s;
        do {    
            ll t = 0;
            for (int i = 0; i<4; ++i)
                for (int j = i+1; j<4; ++j) {
                    t += c[mp[a[j]]][mp[a[i]]]; 
                }
            if (t>maxx) {
                maxx = t;
                string tmp;
                for (int i = 0; i<4; ++i)
                    for (int j = 0; j<c2[mp[a[i]]]; ++j)
                        tmp += a[i];
                ans = tmp;
            }
        } while(next_permutation(a.begin(), a.end()));
        cout << ans << endl;
        clr(c, 0); clr(c2, 0);
    }
	return 0;   
}

Codeforces 1526D - Kill Anton(逆序数)

原文:https://www.cnblogs.com/shuitiangong/p/14827234.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!