题意:
给定n个由字符’s’和字符’h’组成的串,你可以以任意顺序拼接这些串,使得结果串的"sh"子序列数量最多。
输出最大数量。
数据范围:n<=1e5,所有串总长度<=1e5
解法:
令 e [ i ] . a 为 第 i 个 串 中 s 的 个 数 令 e [ i ] . b 为 第 i 个 串 中 h 的 个 数 令 e [ i ] . c 为 第 i 个 串 本 身 的 贡 献 . 显 然 不 管 如 何 排 序 , e [ i ] . c 都 不 会 收 到 影 响 串 拼 接 之 后 的 总 贡 献 为 : a n s = ∑ i = 1 n e [ i ] . c + ∑ i = 1 n p r e [ i ] ∗ e [ i ] . b 其 中 p r e [ i ] 表 示 串 i 左 边 的 字 符 ′ s ′ 的 数 量 . 对 于 两 个 相 邻 串 i , j , 当 前 的 贡 献 为 : p r e ∗ e [ i ] . b + ( p r e + e [ i ] . a ) ∗ e [ j ] . b 对 于 两 个 相 邻 串 j , i , 当 前 的 贡 献 为 : p r e ∗ e [ j ] . b + ( p r e + e [ j ] . a ) ∗ e [ i ] . b 若 i , j 能 使 得 答 案 更 优 , 那 么 必 须 满 足 : p r e ∗ e [ i ] . b + ( p r e + e [ i ] . a ) ∗ e [ j ] . b > p r e ∗ e [ j ] . b + ( p r e + e [ j ] . a ) ∗ e [ i ] . b 化 简 得 : e [ i ] . a ∗ e [ j ] . b > e [ j ] . a ∗ e [ i ] . b 按 照 这 个 规 则 对 e [ ] 排 序 即 可 . 令e[i].a为第i个串中s的个数\\ 令e[i].b为第i个串中h的个数\\ 令e[i].c为第i个串本身的贡献.\\ 显然不管如何排序,e[i].c都不会收到影响\\ 串拼接之后的总贡献为:\\ ans=\sum_{i=1}^ne[i].c+\sum_{i=1}^npre[i]*e[i].b\\ 其中pre[i]表示串i左边的字符's'的数量.\\ 对于两个相邻串i,j,当前的贡献为:\\ pre*e[i].b+(pre+e[i].a)*e[j].b\\ 对于两个相邻串j,i,当前的贡献为:\\ pre*e[j].b+(pre+e[j].a)*e[i].b\\ 若i,j能使得答案更优,那么必须满足:\\ pre*e[i].b+(pre+e[i].a)*e[j].b>pre*e[j].b+(pre+e[j].a)*e[i].b\\ 化简得:\\ e[i].a*e[j].b>e[j].a*e[i].b\\ 按照这个规则对e[]排序即可. 令e[i].a为第i个串中s的个数令e[i].b为第i个串中h的个数令e[i].c为第i个串本身的贡献.显然不管如何排序,e[i].c都不会收到影响串拼接之后的总贡献为:ans=i=1∑ne[i].c+i=1∑npre[i]∗e[i].b其中pre[i]表示串i左边的字符′s′的数量.对于两个相邻串i,j,当前的贡献为:pre∗e[i].b+(pre+e[i].a)∗e[j].b对于两个相邻串j,i,当前的贡献为:pre∗e[j].b+(pre+e[j].a)∗e[i].b若i,j能使得答案更优,那么必须满足:pre∗e[i].b+(pre+e[i].a)∗e[j].b>pre∗e[j].b+(pre+e[j].a)∗e[i].b化简得:e[i].a∗e[j].b>e[j].a∗e[i].b按照这个规则对e[]排序即可.
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
struct Node{
int a,b,c;
}e[maxm];
int n;
bool cmp(Node a,Node b){
return a.a*b.b>b.a*a.b;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
string s;cin>>s;
for(auto x:s){
if(x=='s'){
e[i].a++;
}else{
e[i].b++;
e[i].c+=e[i].a;
}
}
}
sort(e+1,e+1+n,cmp);
int ans=0;
int cnt=0;
for(int i=1;i<=n;i++){
ans+=e[i].c;
ans+=cnt*e[i].b;
cnt+=e[i].a;
}
cout<<ans<<endl;
return 0;
}