题目链接:https://codeforces.com/contest/1733
解题思路:
每个周期里面找最大的就行了。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
int n;
int a[mx];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int k;
scanf("%d%d", &n, &k);
for(int i=1;i<=n;i++)
scanf("%d", a+i);
ll ans = 0;
for (int i=1;i<=k;i++) {
int ma = 0;
for (int j=i;j<=n;j+=k) {
ma = max(ma, a[j]);
}
ans += ma;
}
printf("%lld\n", ans);
}
return 0;
}
解题思路:
必然要有一个是0,因为第一场比赛肯定就有人要输。因此剩下那个数就是要整除的了。然后随便构造一下。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
int n;
int a[mx];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (b > c) swap(b, c);
if (b == 0 && c == 0) {
puts("-1");
} else if(b == 0) {
if ((a - 1) % c == 0) {
int cnt = (a - 1) / c;
for (int i=2; i <= a; i += c) {
for (int j=1;j<=c;j++)
printf("%d ", i);
}
puts("");
} else
puts("-1");
} else
puts("-1");
}
return 0;
}
解题思路:
先把第一个位置和第N个位置弄成一样的,那么接下来就可以用两种中的一种使得i位置的值与第一位或者第N位一样了,因此次数不超过N-1。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
int n;
int a[mx];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i=1;i<=n;i++)
scanf("%d", a+i);
if (n == 1) {
puts("0");
continue;
}
printf("%d\n1 %d\n", n - 1, n);
if ((a[1] + a[n]) % 2 == 0)
a[1] = a[n];
for (int i=2; i<n; i++) {
if ((a[1] + a[i]) % 2 == 0)
printf("%d %d\n", i, n);
else
printf("1 %d\n", i);
}
}
return 0;
}
解题思路:
当a序列和b序列不同的位数是奇数时,那么肯定是误解的。因此实际我们只需要观察a、b相同位置上不同的值就行了。一般情况下值需要操作x/2次,x就是不同值的个数,因为x>=y,因此尽量不要让相邻的两位数进行异或就行了,所以当x == 2时,需要特判一下,可能2次y的操作要小于x。因为a ^ c, b ^ c也能得到a ^ b的效果。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 1e4 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
int n;
char s1[mx], s2[mx];
vector <int> vec;
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, x, y;
scanf("%d%d%d", &n, &x, &y);
scanf("%s", s1 + 1);
scanf("%s", s2 + 1);
vec.clear();
for (int i=1;i<=n;i++) {
if (s1[i] != s2[i])
vec.push_back(i);
}
if (vec.size() & 1)
puts("-1");
else if (vec.size() == 2){
if (vec[0] + 1 == vec[1]) {
if (2 * y < x)
printf("%d\n", 2 * y);
else
printf("%d\n", x);
} else
printf("%d\n", y);
} else {
printf("%lld\n", 1ll * y * vec.size() / 2);
}
}
return 0;
}
解题思路:
D1中已经讨论了x>=y的情况,那么实际在D2中只需要考虑x < y的情况即可。此时,两个位置i,j需要同时操作,他们的花费可以是(j - i) * x,也可以是y。当j - i == 1时,前者花费肯定更小。假设只有(j - i) * x的情况,那么就很简单了,只要从头开始,对[1,2]、[3,4]、[k-1, k],按顺序对每一对进行计算就行了。但是如果引入了y操作,就增加了一种情况,假设[i, j]是进行y操作的,那么在区间[i+1, j-1]之间肯定没有y操作, 因为如果有,那么可以把[i,j]区间划分为更小的y操作,(a,b)、(c,d)可以变成(a,c)、(d、b)。a < c < d < b。知道了这个条件就没有对j去枚举i,i < j,就有
dp[j] = min(dp[j], dp[i-1] + y + sec[i+1][j-1]),sec[i][j]为区间[i,j]只使用x的花费,这个可以直接贪心计算。
dp[j] = min(dp[j], dp[i-1] + dis(i,j) * x+ sec[i+1][j-1])
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 5e3 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
int n;
char s1[mx], s2[mx];
vector <int> vec;
ll sec[mx][mx];
ll dp[mx];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, x, y;
scanf("%d%d%d", &n, &x, &y);
scanf("%s", s1 + 1);
scanf("%s", s2 + 1);
vec.clear();
for (int i=1;i<=n;i++) {
if (s1[i] != s2[i])
vec.push_back(i);
}
if (vec.size() & 1)
puts("-1");
else if (x >= y) {
if (vec.size() == 2) {
if (vec[0] + 1 == vec[1]) {
if (2 * y < x)
printf("%d\n", 2 * y);
else
printf("%d\n", x);
} else
printf("%d\n", y);
} else {
printf("%lld\n", 1ll * y * vec.size() / 2);
}
} else {
for (int i=1; i<=vec.size(); i++) {
for (int j=i+1; j<=vec.size(); j+=2) {
sec[i][j] = 1e16;
int dis = vec[j-1] - vec[j - 2];
sec[i][j] = min(sec[i][j], sec[i][j-2] + 1ll * dis * x);
}
}
for (int i=2; i <= vec.size(); i+=2) {
dp[i] = 1e16;
for (int j=1; j < i; j+=2) {
dp[i] = min(dp[i], dp[j-1] + y + sec[j+1][i-1]);
int dis = vec[i-1] - vec[j-1];
dp[i] = min(dp[i], dp[j-1] + 1ll * dis * x + sec[j+1][i-1]);
}
}
printf("%lld\n", dp[vec.size()]);
}
}
return 0;
}