@dxbdly
2022-10-06T09:01:20.000000Z
字数 2844
阅读 168
2022暑
思维难度:,代码难度:
个相同物品放入 个相同盒子中,盒子非空,求方案数(最小表示后不同即不同)。
。
考虑 DP。
考试的时候好像傻逼了,没推出来。
听说这个转移和第二类 很像。
表示 个球, 个箱子的答案。
转移分两种,一种是全部都多放一个,一种是在最前面放一个
说起来十分简单,但是这转移的分类确实奇怪。
//The Code Is From Dawn#include<bits/stdc++.h>#define int long longusing namespace std;inline int read() {int x = 0;char c = getchar();bool f = 0;while(!isdigit(c)) f |= (c == '-'), c = getchar();while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();return f ? -x : x;}const int maxn = 5005, mod = 998244353;int n, k;int f[maxn][maxn];signed main() {// freopen("A.in", "r", stdin);// freopen("A.out", "w", stdout);n = read(), k = read();for(register int i = 1; i <= n; ++i) f[1][i] = 1;for(register int i = 2; i <= k; ++i)for(register int j = i; j <= n; ++j) {f[i][j] = (f[i - 1][j - 1] + f[i][j - i]) % mod;}printf("%lld\n", f[k][n] % mod);return 0;}
奇奇怪怪的转移分类,积累。
思维难度: 代码难度:
节点树,有边权,找到最小的长度 满足 的路径,输出长度。
。
显然可以二分答案。
那确定了长度,就是一个淀粉质板子判定。
//The Code Is From Dawn#include<bits/stdc++.h>using namespace std;inline int read() {int x = 0;char c = getchar();bool f = 0;while(!isdigit(c)) f |= (c == '-'), c = getchar();while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();return f ? -x : x;}const int maxn = 2e5 + 5, INF = 1e9 + 7;int n, L, R;struct node {int v, nex;int w;}edge[maxn << 1];int head[maxn], len;int Siz[maxn], Maxx[maxn], root, Sum, Answer;int Vst[maxn];inline void make_map(int u, int v, int w) {len++;edge[len].nex = head[u];edge[len].v = v;edge[len].w = w;head[u] = len;}inline void Get_Siz(int x, int fa) {Siz[x] = 1;for(register int i = head[x]; i; i = edge[i].nex) {int y = edge[i].v, z = edge[i].w;if(y == fa) continue;Get_Siz(y, x), Siz[x] += Siz[y];}}inline int Get_Rt(int x, int fa) {int s = 1; Maxx[x] = 0;for(register int i = head[x]; i; i = edge[i].nex) {int y = edge[i].v, z = edge[i].w;if(y == fa || Vst[y]) continue;int nex = Get_Rt(y, x); s += nex;Maxx[x] = max(Maxx[x], nex);}Maxx[x] = max(Maxx[x], Sum - s);if(Maxx[x] < Maxx[root]) root = x;return s;}inline set<int> Calc(int x, int fa) {set<int> now; now.insert(0);for(register int i = head[x]; i; i = edge[i].nex) {int y = edge[i].v, z = edge[i].w;if(y == fa || Vst[y]) continue;set <int> Nex = Calc(y, x);for(auto j : Nex) now.insert(z + j);}return now;}inline void Solve(int x) {set<int> now; now.insert(0), Vst[x] = 1;for(register int i = head[x]; i; i = edge[i].nex) {int y = edge[i].v, z = edge[i].w;;if(Vst[y]) continue;set <int> Nex = Calc(y, x); set <int> :: iterator It;for(auto j : Nex) {It = now.lower_bound(L - j - z);if(It != now.end()) Answer = min(Answer, *It + j + z);}for(auto j : Nex) now.insert(j + z);Solve(y);}}int main() {// freopen("B.in", "r", stdin);// freopen("B.out", "w", stdout);n = read(), L = read(), R = read();for(register int i = 1; i < n; ++i) {int u = read(), v = read(), w = read();make_map(u, v, w), make_map(v, u, w);}Answer = INF, Solve(1);if(Answer > R) printf("-1\n");else printf("%d\n", Answer);return 0;}
寄在不会淀粉质。
思维难度:,代码难度:
求满足 的无序数对 的个数。
。
异或可逆,所以
那么有: