#include<bits/stdc++.h> usingnamespace std; using LL = longlong; constint N = 20, MOD = 998244353, INF = 0x3f3f3f3f;
int n, m; int a[N]; voiddfs(int x, int cnt){ if (cnt == m) { for (int i = 1; i <= m; ++ i) { cout << a[i] << " \n"[i == m]; } return; } for (int i = x + 1; i <= n; ++ i) { a[cnt + 1] = i; dfs(i, cnt + 1); } } signedmain(){ cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> m; swap(n, m); dfs(0, 0); return0; }
D - Left Right Operation
题目描述
一个长度为 $n$ 的序列,允许你进行若干次如下操作
选择一个数 $x$ ,将 $a_1,a_2, \cdots ,a_{1+x-1}$ 全部置为 L
选择一个数 $y$ ,将 $a_{n-y+1}, \cdots ,a_{n-1},a_n$ 全部置为 R
求最终 $\sum_{1}^{n}a_i$ 的最小值。
思路
一开始想的贪心,错了几次之后改为 $dp$ 了。
设 $f_{i,0}$ 为 $a_i$ 不变为 L 时的前缀最小值,相应的 $f_{i,1}$ 为 $a_i$ 变为 L 时的前缀最小值。
设 $g_{i,0}$ 为 $a_i$ 不变为 R 时的后缀最小值,相应的 $g_{i,1}$ 为 $a_i$ 变为 R 时的后缀最小值。
#include<bits/stdc++.h> usingnamespace std; using LL = longlong; constint N = 2e5 + 5, MOD = 998244353, INF = 0x3f3f3f3f;
int n, a[N], dp[N]; structFenWick { int n; vector< int > c; FenWick(int n) : n(n), c(n + 1) {} voidadd(int i, int d){ for (; i <= n; i += i & -i) { c[i] += d; c[i] %= MOD; } } voidadd(int l, int r, int d){ add(l, d); add(r + 1, -d); } intget(int i){ int sum = 0; for (; i; i -= i & -i) { sum += c[i]; sum %= MOD; } return sum; } intget(int l, int r){ return (get(r) - get(l - 1) + MOD) % MOD; } }; LL ksm(LL x, LL y, LL res = 1){ for (; y; y >>= 1, x = x * x % MOD) { if (y & 1) { res = res * x % MOD; } } return res; } signedmain(){ cin.tie(nullptr)->sync_with_stdio(false);
cin >> n; for (int i = 1; i < n; ++ i) { cin >> a[i]; } FenWick d(n); for (int i = n - 1; i >= 1; -- i) { dp[i] = (1 + (d.get(i + 1, i + a[i]) + 1) % MOD * ksm(a[i], MOD - 2) % MOD) % MOD; d.add(i, dp[i]); } cout << dp[1] << '\n'; return0; }
#include<bits/stdc++.h> usingnamespace std; using LL = longlong;
#define int LL constint N = 300, INF = 1e12; structEdge { int from, to, cap, flow;
Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; structDinic { int n, m, S, T; vector< Edge > edges; vector< int > G[N]; int d[N], cur[N]; bool vis[N];
Dinic(int S, int T) : S(S), T(T) {} voidAddEdge(int from, int to, int cap){ edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); }
boolBFS(){ memset(vis, false, sizeof(vis)); queue<int> Q; Q.push(S); d[T] = 0; vis[S] = true; while (!Q.empty()) { int x = Q.front(); Q.pop(); for (int i = 0; i < G[x].size(); ++ i) { Edge& e = edges[G[x][i]]; if (!vis[e.to] && e.cap > e.flow) { vis[e.to] = true; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[T]; }
intDFS(int x, int a){ if (x == T || a == 0) { return a; } int flow = 0, f; for (int& i = cur[x]; i < G[x].size(); ++ i) { Edge& e = edges[G[x][i]]; if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a == 0) { break; } } } return flow; }
intMaxflow(){ int flow = 0; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(S, INF); } return flow; } }; int v[30000005], prime[30000005], tot; voidpre(){ for (int i = 2; i <= 30000000; ++ i) { if (!v[i]) { v[i] = i; prime[++ tot] = i; } for (int j = 1; j <= tot && 1LL * prime[j] * i <= 30000000; ++ j) { if (prime[j] > v[i]) { break; } v[prime[j] * i] = prime[j]; } } } int n; pair< int, int > a[N]; signedmain(){ cin.tie(nullptr)->sync_with_stdio(false);
pre(); cin >> n; for (int i = 1; i <= n; ++ i) { int x, y; cin >> x >> y; a[i] = {x, y}; } Dinic d(0, 250); for (int i = 1; i <= n; ++ i) { d.AddEdge(0, i, a[i].second); d.AddEdge(i + n, 250, a[i].second); } for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= n; ++ j) { if (v[a[i].first + a[j].first] == a[i].first + a[j].first) { d.AddEdge(i, j + n, INF); } } } cout << d.Maxflow() / 2 << '\n'; return0; }