A. Add Candies
题意:n个位置,第
i
i
i 个位置的值是
i
i
i,第
i
i
i 次操作除了选择的位置以为外,每个位置都加
i
i
i。求一个方案使得最终的所有位置数相等
比较有意思的一道题
考虑
n
n
n 的前
n
n
n 项和
s
u
m
sum
sum作为最终的相等值
因为操作是第
i
i
i 次选择一个位置,除了这个位置之外的数都加
i
i
i
1—>sum 不用加1
2—>sum 不用加2
…
发现通解就是 n次操作,从1到n依次输出即可
B. Numbers Box
题意:给你一个矩阵,每个位置有一个数,范围是 -100 到 100,每次操作可以将两个相邻的数分别成-1,变成它们的相反数。
根据这个操作的性质,我们可以发现如果矩阵里有负数,我们可以利用这个操作转移符号。
如果矩阵中有0,那么就可以将全部的负号转移到0上,答案为所有数的绝对值之和
如果没有0,我们可以两两负数进行消除负号,因此最后至多只有一个负数,统计一下负数的个数,偶数个答案就是所有数绝对值之和,奇数个就把绝对值最小的一个数最为最后的负数
C. Knapsack
贪心
D. Catching Cheaters
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示以
A
i
A_i
Ai ,
B
j
B_j
Bj 结尾的最大相似度评分
如果
A
i
=
B
i
A_i = B_i
Ai=Bi,那么
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
−
1
]
+
2
f[i][j] = f[i-1][j-1] + 2
f[i][j]=f[i−1][j−1]+2
否则
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
−
1
]
[
j
]
−
1
,
f
[
i
]
[
j
−
1
]
−
1
,
f
[
i
]
[
j
]
)
f[i][j] = max(f[i-1][j]-1, f[i][j-1]-1, f[i][j])
f[i][j]=max(f[i−1][j]−1,f[i][j−1]−1,f[i][j])
时间复杂度
O
(
n
∗
m
)
O(n*m)
O(n∗m)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 5e3 + 9;
int n, m;
char a[maxn], b[maxn];
int f[maxn][maxn];
void work()
{
cin >> n >> m;
scanf("%s", a + 1);
scanf("%s", b + 1);
int ans = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
f[i][j] = 0;
if(i && j && a[i] == b[j])
f[i][j] = max(f[i][j], f[i-1][j-1] + 2);
else f[i][j] = max({f[i-1][j]-1, f[i][j-1]-1, f[i][j]});
ans = max(ans, f[i][j]);
}
cout << ans << endl;
}
int main()
{
//int TT;cin>>TT;while(TT--)
work();
return 0;
}