题目链接:
https://vjudge.net/contest/292025#problem/D
题目描述:
给你n个由 's' 与 'h' 构成的字符串,让你把他们拼成一个长串,问你总价值最大值是多少?(总价值计算方式:对于每一个 'h' 位置的价值为:ta前面 ’s‘的个数,'s' 位置的价值为0,所以总价值就是把左右 'h' 位置的价值加起来)。
为了方便描述题目换了种说法,意思就是这个意思~~~
题解:
首先这是一个类型的思维问题! 不仅仅适用于该题目,这种思维方式可以用于多种场景。
那么有个很容易发现的问题,那么我肯定想前面s尽可能多,后面h尽可能多。那么怎么做到呢?
那么咱们拿两个字符串来举例子: ssh 与 hhhs
对于他们俩谁放在前面好呢? 计算一下! 如果是 sshhhhs 那么价值为:8 如果是 hhhsssh 那么价值为:3
所以我们肯定要按照 sshhhhs 这个顺序来计算,那么对于两个成立,如果对于 n 个呢?
大家应该很容易发现这个关系ta具有传递性,所以对于n个也是成立的,如果不信可以那 3 个串自己手动模拟一下。
所以就按照这个传递性,排一个序就出来了。
AC代码:
#include<bits/stdc++.h>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define maxn ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
string str[maxn];
ll fun(string str) //计算一个串的价值
{
ll num = 0, ans = 0;
for(int i = 0; i < str.length(); i++)
{
if(str[i] == 's') num++; //记录当前s出现的个数
else ans += num; //当碰到h计算价值,h的价值就是ta前面 s 的个数
}
return ans;
}
bool cmp(string a, string b)
{
string str = "", str2 = "";
str += a; str += b;
str2 += b; str2 += a;
if(fun(str) > fun(str2)) return 1;
else return 0;
}
int main()
{
int n; cin>>n;
up(i, 1, n) cin>>str[i];
sort(str + 1, str + 1 + n, cmp);//排序
string all = "";
up(i, 1, n)
{
all += str[i];
}
ll ans = fun(all); //计算
cout<<ans;
}