D. Kill Anton
思路:
这题和南京站的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;
}
codeforces补题 文章被收录于专栏
NULL