感觉前面几题难度貌似不是那么难(-V-),不过 虽然
,都没意识到假了。。
A. Cidoai的幂次序列
思路
对于序列 ,
+
+
,是满足条件的。
复杂度
时间复杂度和空间复杂度均为
代码实现
// Problem: Cidoai的幂次序列
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/88880/A
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int n, k;
cin >> n >> k;
cout << 2 << '\n';
cout << n - 1 << ' ' << 1 << '\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
B. Cidoai的平均数对
思路
令选择出的下标序列为 ,序列的长度为
,若该下标序列满足
的平均数不超过
,那么
。
此时的问题则可以转换为,选出一个下标序列,下标序列每一项对应的 之和不超过
的情况下,能取到对应
之和的最大值。
可以用背包 解决这个问题,令
为在前
对数中选,满足
之和为
的序列对应的
之和最大值。
初始化时,设置 ,表示还未取数对的情况,其他设置为
。
此时 ,
为不选
的情况,
为选择
的情况。
因为 ,所以
的取值范围最大为
,计算状态时枚举这个范围的
即可。
因为第二维的 涉及到负数,所以在代码实现的时候可以加上一个偏移量
,使得数组下标不越界。
直接按上面的状态表示定义数组,数组大小最大为 ,会超过空间限制,所以需要滚动优化,每次只保留上一层状态,计算时第一维对应的上一层则从
变为
,用相邻下标奇偶性相反的性质表示上一层。
复杂度
时间复杂度为 ,空间复杂度为
代码实现
// Problem: Cidoai的平均数对
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/88880/B
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 501, M = N * N;
int n, k;
int f[2][2 * M + N];
// 因为 bi - k 可能为负数,所以需要加一些空间防止越界
void solve()
{
cin >> n >> k;
memset(f, -0x3f, sizeof(f));
f[0][M - k] = 0;
for (int i = 1; i <= n; i++) {
int a, b;
cin >> a >> b;
b -= k;
int op = i % 2;
for (int j = 0; j < 2 * M; j++) {
f[op][j] = f[op ^ 1][j];
if (j >= b) {
f[op][j] = max(f[op][j], f[op ^ 1][j - b] + a);
}
}
}
int ans = 0;
for (int i = 0; i <= M - k; i++) {
ans = max(ans, f[n % 2][i]);
}
cout << ans;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
C. Cidoai的树上方案
思路
令 为以节点
不与树外点连边,以该节点为根的子树与树外点连若干条边不含三元环的方案数,
同理,表示的是节点
与树外点连边的情况。
树外一点要连接树上的点构成三元环,那么肯定是选树上相邻的两个点进行连边。
因此,若父节点不与树外点连边,那么子节点和树外点可以连边也可以不连边,否则,子节点必然不能与树外点连边。
那么对于非叶子节点 ,
,
(
为
的子节点)。
对于叶子节点 ,与树外点相连和不连都是一种情况,所以
。
复杂度
时间复杂度 ,空间复杂度
。
代码实现
// Problem: Cidoai的树上方案
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/88880/C
// Memory Limit: 524288 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e6 + 5, mod = 998244353;
int n;
int f[N][2];
vector<int> h[N];
void dfs(int u)
{
f[u][0] = f[u][1] = 1;
for (int v : h[u]) {
dfs(v);
f[u][0] *= (f[v][0] + f[v][1]) % mod;
f[u][0] %= mod;
f[u][1] *= f[v][0];
f[u][1] %= mod;
}
}
void solve()
{
cin >> n;
for (int i = 2; i <= n; i++) {
int j;
cin >> j;
h[j].push_back(i);
}
dfs(1);
int ans = (f[1][0] + f[1][1]) % mod;
cout << ans;
}
signed main()
{
ios::sync_with_stdio(0);,
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}