且歌且行,眉目轻盈。何妨吟啸且徐行。|

胖柚の工作室

园龄:2年1个月粉丝:2关注:15

2024-08-15 21:44阅读: 7评论: 0推荐: 0

AtCoder Beginner Contest 044

A - Tak and Hotels (ABC Edit)

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, k, x, y;
cin >> n >> k >> x >> y;
int ans = 0;
if (n <= k) {
ans += n * x;
} else {
ans += k * x + (n - k) * y;
}
cout << ans;
return 0;
}

B - Beautiful Strings

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int st[26];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
string s;
cin >> s;
for (auto i : s) {
st[i - 'a'] ++;
}
for (int i = 0; i < 26; i++) {
if (st[i] % 2 == 1) {
cout << "No\n";
return 0;
}
}
cout << "Yes";
return 0;
}

C - Tak and Cards

f[i][j][k] 表示前 i 个物品中,选择 j 个物品,价值之和为 k 的方案数。状态转移方程为:dp[i][j][k]=dp[i1][j][k]+dp[i1][j1][kx[i]]确保不要访问到负数下标,下标从1开始

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
long long f[51][51][2600], pre[1005];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int N, A;
cin >> N >> A;
vector<int> x(N + 1);
for (int i = 1; i <= N; i++) {
cin >> x[i];
pre[i] = pre[i - 1] + x[i];
}
for (int i = 0; i <= N; i++) f[i][0][0] = 1;//初始化,啥都不选也是一种方案
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= i; j++) {
for (int k = 1; k <= pre[i]; k++) {
if (k >= x[i]) f[i][j][k] += f[i - 1][j - 1][k - x[i]];
f[i][j][k] += f[i - 1][j][k];
}
}
}
long long ans = 0;
for (int i = 1; i <= N; i++) ans += f[N][i][A * i];
cout << ans;
return 0;
}

其实这就是变形后的 01 背包问题,可以将第一维优化掉,但需注意改变循环的遍历顺序,从小到大的状态更新方式,若仍然顺序遍历的话,被忽略的 i1 维度的 jk 会被污染,影响状态转移。因此需要逆向枚举

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
long long f[51][2600], pre[1005];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int N, A;
cin >> N >> A;
vector<int> x(N + 1);
for (int i = 1; i <= N; i++) {
cin >> x[i];
pre[i] = pre[i - 1] + x[i];
}
f[0][0] = 1;
for (int i = 1; i <= N; i++) {
for (int j = i; j >= 1; j--) {
for (int k = pre[i]; k >= x[i]; k--) {
f[j][k] += f[j - 1][k - x[i]];
}
}
}
long long ans = 0;
for (int i = 1; i <= N; i++) ans += f[i][A * i];
cout << ans;
return 0;
}

本文作者:胖柚の工作室

本文链接:https://www.cnblogs.com/pangyou3s/p/18361856

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   胖柚の工作室  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起