思路:
这题和南京站的Evil Coordinate有着异曲同工之妙。南京的那题的解法也是一定存在某个最优情况中,相同类型的字母连续出现,然后只需要枚举种情况就可以找到最优解。南京那题我不会证,但是多画几个图后发现找不到反例,感觉也有点道理,这题看了一下证明没看懂,感觉是就是吧。
枚举出来一个状态后计算恢复它最小需要多少步可以用到前缀和,,每个前面的数量分别为,那么需要的最小的步数就是;每个前面的数量分别为,那么需要的最小的步数就是
MyCode:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 7, mod = 1e9 + 7; string s,tmp="ANTO"; int mp[26],n; ll f[4][4],cnt[4]; inline void solve() { cin>>s; n=s.size(); memset(f,0,sizeof f); memset(cnt,0,sizeof cnt); for(char i:s) cnt[mp[i-'A']]+=1; for(int i=0; i<4; ++i) { ll sum(0); for(int j=0; j<n; ++j) { f[i][mp[s[j]-'A']]+=sum; if(s[j]==tmp[i]) sum+=1; } } ll mx=-1; vector<int>ans,v= {0,1,2,3}; do { ll num(0); for(int i=0; i<4; ++i) for(int j=i+1; j<4; ++j) num+=f[v[j]][v[i]]; if(num>mx) { mx=num; ans=v; } } while(next_permutation(v.begin(),v.end())); for(int &i:ans) for(int j=0; j<cnt[i]; ++j) cout<<tmp[i]; cout<<'\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); int _; mp[0]=0,mp['N'-'A']=1,mp['T'-'A']=2,mp['O'-'A']=3; cin>>_; while(_--) solve(); return 0; }