文章目录
2019-2020 ICPC Southeastern European Regional Programming Contest (SEERC 2019)
B. Level Up
题意: s1和s2为level1和level2所需经验值;现在有n个任务,每个任务只能做一次,第i个任务在level1时需要 ti的时间,可以涨 xi经验值,在level2时使用时需要 ri的时间,可以涨yi的经验值。只有升完level1才能升level2,在level1溢出的经验值算到level2上。问升完2级所需要的最小时间。
题解:
设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]为完成前i个任务,在level1时获得经验为j在level2时获得经验为k时所需的最小时间,然后更新即可
注意需要先将任务按照x从小到大排序,因为这样才能获得更多的溢出经验
在实现的时候第一维可以滚动掉
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e2 + 5;
typedef long long LL;
#define int LL
int n, s1, s2;
struct node {
int x, y, r, t;
} a[N];
int dp[N][N];
bool cmp(node a, node b) {
return a.x < b.x; }
int sum = 0;
signed main() {
cin >> n >> s1 >> s2;
for (int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].t >> a[i].y >> a[i].r;
sum += a[i].x;
}
sort(a + 1, a + 1 + n, cmp);
memset(dp, 0x3f, sizeof dp);
dp[0][0] = 0;
int res = 0x3f3f3f3f;
for (int i = 1; i <= n; i++) {
for (int j = s1; j >= 0; j--) {
for (int k = s2; k >= 0; k--) {
if (dp[j][k] != 0x3f3f3f3f) {
int nj, nk;
if (j < s1) {
nj = j + a[i].x, nk = k;
if (nj > s1) {
nk = min(s2, k + nj - s1);
nj = s1;
}
dp[nj][nk] = min(dp[nj][nk], dp[j][k] + a[i].t);
}
nk = min(s2, k + a[i].y);
dp[j][nk] = min(dp[j][nk], dp[j][k] + a[i].r);
}
}
}
}
if (dp[s1][s2] == 0x3f3f3f3f3f3f3f3f) {
cout << -1 << endl;
} else {
cout << dp[s1][s2] << endl;
}
return 0;
}
D. Cycle String?
题意: 给你一个字符串,问你能否将字符串的位置改变使得字符串中不存在2个长度为n的相同的子串。 1 < = 2 ∗ n < = 1 0 6 1<=2*n<=10^6 1<=2∗n<=106
题解: 思维+构造。因为只会存在一种字符长度大于等于n,因此我们只需要考虑处理这种字符。记这种字符为a,那么构造出来的序列为aaabaaabaaacaaada,这样每出现n次a,就插入一个其他的字符隔开。但是要考虑一种特殊情况,比如aaabaaab,这样就会导致aaba出现重复,这种情况为a的出现次数为2 * n - 2,其他字符出现2次,特判即可。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int const MAXN = 2e6 + 10;
int num[MAXN];
char ans[MAXN];
int