寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄|

TLE_Automation

园龄:2年9个月粉丝:19关注:23

P8153 题解

思路来自:@wsyear 大佬,十分感谢。

题意:

给你 n01 字符串,每次取一个串后删除第一个字符,将剩下的串加入到答案串中,最大化答案串中相邻字符相等的对数。

思路:

  • Sub1:爆搜。

我的爆搜写的比较奇怪。

记录
暴力代码

  • Sub2,Sub3

我们考虑贪心,首先我们把所有的字串全加进去是最优的,因为有更多的字符就有更多的可能去最大化答案串中相邻字符相等的对数。

既然是全加进去,每个字串中间是什么无法改变,只能改变头尾相接的顺序,所以我们预处理出所有串的字串中相等的对数。

这个时候我们就只需要考虑每个串的头和尾了,头尾相接有 4 中情况:

  • 1 0

  • 1 1

  • 0 1

  • 0 0

我们只需要统计出以 1 为前缀,后缀的串的个数,以 0 为前缀的串的个数即可。

我们还要考虑这个答案串一开始是要填 0 还是填 1

所以我们将一开始填 0 和一开始填 1 的情况做比较即可。

AC code:

/*
work by: TLE_Automation
Time: O(轻轻松松过)
knowledge: 垃圾算法
*/
#include<bits/stdc++.h>
#define il inline
#define re register
#define Orz puts("Szt Lps Fjh AK IOI!");
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
// #define int long long
using namespace std;
const int INF = 1e9 + 7, mod = 1e9 + 7;
const int maxn = 2e5 + 10, MAXN = 3e3 + 10, N = 1e6 + 10;
typedef long long LL;
string s[N];
LL ans, n;
int L[N], sum = 0;
bool f1, f2;
int sum1, sum2, sum3, sum4;
// sum1 是以 0 为后缀的串的个数
// sum2 是以 1 为后缀的串的个数
// sum3 是以 0 为前缀的串的个数
// sum4 是以 1 为前缀的串的个数
// f1 是否有开头就是 0 的
// f2 是否有开头就是 1 的
signed main() {
IOS
cin >> n;
for(re int i = 1; i <= n; i++) cin >> s[i], s[i] = "$" + s[i], L[i] = s[i].length() - 1;
for(re int i = 1; i <= n; i++) sum += L[i];
// for(int i = 1; i <= n; i++) cout << L[i] << " ";
if(!(sum ^ n)) return printf("0"), 0;
for(re int i = 1; i <= n; i++) {
int cnt = 0;
for(re int j = L[i] - 1; j >= 2; j--) {
if(s[i][j] == s[i][j + 1]) cnt++;
ans += cnt;
}
}
// cout << ans << endl;
for(re int i = 1; i <= n; i++) {
if(L[i] == 1) continue; // 长度为 1 的串删完就成了空串,没用
if(s[i][L[i]] == '0') sum1 += L[i] - 1;
else sum2 += L[i] - 1;
for(re int j = 2; j <= L[i]; j++) {
if(s[i][j] == '0') sum3++;
else sum4++;
}
if(s[i][2] == '0') f1 = true;
else if(s[i][2] == '1') f2 = true;
}
if(f1 && f2) ans += max(min(sum3, sum1) + min(sum4 - 1, sum2), min(sum3 - 1, sum1) + min(sum4, sum2));
else if(f1) ans += min(sum3 - 1, sum1) + min(sum4, sum2);
else ans += min(sum3, sum1) + min(sum4 - 1, sum2);
cout << ans << endl;
}

本文作者:TLE_Automation

本文链接:https://www.cnblogs.com/tttttttle/p/16293595.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   TLE_Automation  阅读(295)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起