Educational Codeforces Round 154 (Rated for Div. 2)
1.Atcoder Beginner Contest 3122.Educational Codeforces Round 152 (Rated for Div. 2)3.Codeforces Round 889 (Div. 2)4.Codeforces Round 888 (Div. 3)5.Codeforces Round 847 (Div. 3)6.Codeforces Round 890 (Div. 2)7.Codeforces Round 892 (Div. 2)8.Codeforces Round 893 (Div. 2)9.Educational Codeforces Round 15310.Codeforces Round 891 (Div. 3)11.Codeforces Round 894 (Div. 3)
12.Educational Codeforces Round 154 (Rated for Div. 2)
13.Codeforces Round 896 (Div. 2)14.Codeforces Round 855 (Div. 3)15.codeforces round 895 (div. 3)16.Codeforces Round 900 (Div. 3)17.Codeforces Round 901 (Div. 2)18.Codeforces Round 903 (Div. 3)C
题意:
一开始有个空数组,以及一串操作s:
s[i] = +:向空数组末尾中加入一个数
s[i] = -:在数组末尾减去一个数
s[i] = 1:当前数组是递增数组
s[i] = 0:当前数组不是递增数组
问s是否是合法的操作
思路:
非法操作说明当前的 0 和 1 冲突了,当前查询和上一次查询冲突了,因为只关心之前的数组状态,所以令b[len]表示数组长度为len时要求的状态,b[len] = 1表示要求数组长度为len时是递增,b[len] = -1表示要求数组长度为len时是不递增的,b[len] = 0 表示没要求
inline void solve()
{
string s; cin >> s;
std::vector<int> b(s.size() + 1);
int len = 0;
bool ans = true;
b[0] = 1, b[1] = 1;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '+')
{
if (b[len] == -1) b[len + 1] = -1;
len++;
}
if (s[i] == '-')
{
if (b[len] == 1 && len >= 2)
{
b[len] = 0;
b[len - 1] = 1;
}
if (b[len] == -1)
{
b[len] = 0;
}
len--;
if (len < 0)
{
ans = false;
break;
}
}
if (s[i] == '1')
{
if (b[len] == -1)
{
ans = false;
break;
}
b[len] = 1;
}
if (s[i] == '0')
{
if (len < 2)
{
ans = false;
break;
}
if (b[len] == 1)
{
ans = false;
break;
}
b[len] = -1;
}
}
if (ans) cout << "YES" << endl;
else cout << "NO" << endl;
}
D
题意:
给定一个数组,每次操作可以选择三个数l, r, x; 让区间[l, r]的数都乘以x,问最少多少次操作可以让数组变成严格单调递增
思路:
因为x可以任意选,所以最终数组中每个数都要么是{负无穷,原数,正无穷}中的一个,定义状态方程为f[i][j]: 让前i个数单调且第i个数的情况为j的最少操作数
f[i][0]: 负无穷, f[i][1]: 原数,f[i][2]: 正无穷
转移方程:先区分a[i]和a[i - 1]的大小,以及当前状态可以由哪些状态转移过来
inline void solve()
{
int n; cin >> n;
std::vector<int> a(n);
memset(f, 0x3f, sizeof(f));
for (int i = 0; i < n; i++)
cin >> a[i];
f[0][0] = 1; f[0][1] = 0; f[0][2] = 1;
for (int i = 1; i < n; i++)
{
if (a[i] >= a[i - 1]) f[i][0] = f[i - 1][0] + 1; // 负数要反过来,因为大数乘上负数就变小了
else f[i][0] = f[i - 1][0];
if (a[i] > a[i - 1])
{
f[i][1] = min(f[i - 1][0], f[i - 1][1]);
f[i][2] = min(min(f[i - 1][0], f[i - 1][1]) + 1, f[i - 1][2]);
}
else
{
f[i][1] = f[i - 1][0];
f[i][2] = min(min(f[i - 1][0], f[i - 1][1]), f[i - 1][2]) + 1;
}
}
int ans = inf;
for (int i = 0; i < 3; i++)
ans = min(ans, f[n - 1][i]);
cout << ans << endl;
}
本文作者:自动机
本文链接:https://www.cnblogs.com/monituihuo/articles/17686090.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步