20260911 每日 1.0 3.0 4.0
No.773 竞赛
https://yukicoder.me/problems/no/773
Note
给定无法参赛的时间 $[A,B]$,问 $23, 24,25$ 日能参加几天
随便写一下
namespace XK {
void solve() {
int A, B; in(A, B);
V<int> x(32, 0);
Rep(i, A, B + 1) x[i] = 1;
ll ans = 0;
Rep(i, 23, 26) if(x[i]) ans ++;
out(3 - ans);
}
};No.3561 收集 KCPC
https://yukicoder.me/problems/no/3561
Note
一个有向图上,有边权,每个点有一个字母,问能不能找到一条从 $1$ 开始,每一次可选收不收集点上的字母,手中的字母按顺序构成 KCPC。有的话输出最小的代价,反之 -1。
这里给出部分点 3 的解法,也就是保证图是 DAG。
可以考虑按照拓扑序列 做 自动机 DP。
当 $S_i = T_i$ 的时候: $f_{v,i + 1} = \text{min}{e[u] = v}(f{u,i} + \text{cost}_{u, v})$
如果不相等的时候就不取:$f_{v,i} = \text{min}{e[u] = v}(f{u,i} + \text{cost}_{u, v})$
于是可以写出:
namespace XK {
void solve() {
int N, M; in(N, M);
V<V<pair<int, int>>> e(N), re(N);
V<int> deg(N, 0);
// map<pair<int, int>, int> mp;
rep(_, M) {
int u, v, w; in(u, v, w); -- u, -- v;
// mp[{u, v}] = w;
e[u].pb({v, w});
re[v].pb({u, w});
deg[v] ++;
}
V<V<int>> f(N, V<int>(5, LINF));
const char T[] = "KCPC";
string S; in(S);
f[0][0] = 0;
queue<int> q;
rep(i, N) if(deg[i] == 0) q.push(i);
V<int> topo;
while(!empty(q)) {
int u = q.front(); q.pop();
topo.pb(u);
for(auto [v, w] : e[u]) {
deg[v] --;
if(!deg[v]) q.push(v);
}
}
for(auto v : topo) {
for(auto [u, w] : re[v]) {
rep(i, 5) if(f[u][i] < LINF) chmin(f[v][i], f[u][i] + w);
}
V<ll> nf = f[v];
rep(i, 4) if(S[v] == T[i] && nf[i] < LINF)
chmin(f[v][i + 1], nf[i]);
}
ll ans = LINF;
rep(i, N) chmin(ans, f[i][4]);
out((ans == LINF ? -1 : ans));
}
};先这样,剩下的明天更新