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
\(\rm f[i][j][k]\) 表示前 \(i\) 个物品中,选择 \(j\) 个物品,价值之和为 \(k\) 的方案数。状态转移方程为:\(dp[i][j][k]=dp[i-1][j][k]+dp[i-1][j-1][k-x[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\) 背包问题,可以将第一维优化掉,但需注意改变循环的遍历顺序,从小到大的状态更新方式,若仍然顺序遍历的话,被忽略的 \(i-1\) 维度的 \(j\) 和 \(k\) 会被污染,影响状态转移。因此需要逆向枚举。
#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;
}
标签:pre,AtCoder,false,Beginner,int,cin,long,using,044
From: https://www.cnblogs.com/pangyou3s/p/18361856