Problem F Greedy Sequence
题目链接:https://nanti.jisuanke.com/t/41303
题意: 给出n个整数,构造s1,s2,s3…sns1,s2,s3…sn,sisi满足五个条件
- s1[i]=i
- 对于1<j<=n,si[j]<si[j−1];
- 对于任意的si[j]在a串中的位置pos[j],满足∣pos[j]−pos[j−1]∣<=k,且si中的每一个数字只能a中出现一次;
- 如果选择的si长度小于n,其余位置就填0;
- 尽量使bi足够大(能得到的最大字典序);
思路: 这题数据真的水,线段树都不用,直接暴力,从i到n,找第i之前出现的符合条件最大的数,答案是找到的数的结果+1。
Accepted Code:
/*
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int ans[MAXN], pos[MAXN];
int main() {
int t, n, k, x;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &k);
memset(ans, 0, sizeof(ans));
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
pos[x] = i;
}
ans[1] = 1;
printf("%d", ans[1]);
for (int i = 2; i <= n; i++) {
ans[i] = 1;
for (int j = i - 1; j >= 1; j--) {
if (abs(pos[j] - pos[i]) <= k) {
ans[i] = ans[j] + 1;
break;
}
}
printf(" %d", ans[i]);
}
printf("\n");
}
return 0;
}
Problem H Holy Grail
题目链接:https://nanti.jisuanke.com/t/41305
题意: 给你n个点,m条边的图,边的权值有正有负。并且原图没有重边和负环,现在给你6个顶点和终点,让你添加6条边,并且要保证添加后图无负环,输出添加的每条边的最小值。
思路: 因为要添加一个边,并且要求无负环,所以要加上一个反向的相反权值,正好将它抵消。Spfa纪录起点终点间的最短距离,然后给他们添加一条边,权值是反向最短距离取负值。
Accepted Code:
/*
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 305;
const int MAXM = 510;
struct edge {
int u, v, w;
edge() {}
edge(int u, int v, int w) : u(u), v(v), w(w) {}
}e[MAXM];
bool vis[MAXN];
int dis[MAXN], f[MAXN], cnt, n;
void Add(int u, int v, int w) {
e[++cnt] = edge(f[u], v, w);
f[u] = cnt;
}
void init() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, false, sizeof(vis));
}
void Spfa(int s) {
init();
queue <int> Q;
Q.push(s);
dis[s] = 0;
vis[s] = true;
while (!Q.empty()) {
int u = Q.front();
Q.pop();
vis[u] = false;
for (int i = f[u]; ~i; i = e[i].u) {
int v = e[i].v;
if (dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
if (!vis[v]) {
vis[v] = true;
Q.push(v);
}
}
}
}
}
int main() {
int t, m;
scanf("%d", &t);
while (t--) {
cnt = 0;
scanf("%d%d", &n, &m);
memset(f, -1, sizeof(f));
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
Add(u, v, w);
}
int q = 6;
while (q--) {
int u, v;
scanf("%d%d", &u, &v);
Spfa(v);
Add(u, v, -dis[u]);
printf("%d\n", -dis[u]);
}
}
return 0;
}