20240912 随机训练
Yukicoder 2867
题目描述
求有多少个正整数
。 的十进制表示下不存在连续的 。
思路
由于
令
按此状态转移即可。(转移太复杂了,此处省略)
时空复杂度均为
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000005, MOD = 998244353;
int n, f[MAXN][2][3], ans;
string s;
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> s;
n = s.size(), s = ' ' + s;
f[0][1][0] = 1;
for(int i = 0; i < n; ++i) {
for(bool lim : {0, 1}) {
for(int op : {0, 1, 2}) {
int r = s[i + 1] - '0';
for(int num = 0; num <= (lim ? r : 9); ++num) {
if(!(op == 2 && num == 4)) {
f[i + 1][lim & (num == r)][(num == 4 ? 1 : (op == 1 && num == 0 ? 2 : 0))] = (f[i + 1][lim & (num == r)][(num == 4 ? 1 : (op == 1 && num == 0 ? 2 : 0))] + f[i][lim][op]) % MOD;
}
}
}
}
}
for(bool lim : {0, 1}) {
for(int op : {0, 1, 2}) {
ans = (ans + f[n][lim][op]) % MOD;
}
}
cout << (ans - 1 + MOD) % MOD;
return 0;
}
Yukicoder 2869
题目描述
你有
你可以往背包里放物品,使得这些物品的重量之和
求最大的放入的物品价值之和,并给出方案。
思路
观察到
令
我们可以预处理
然后转移时就枚举
由于我们每次刚好枚举
空间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 17;
const ll INF = (ll)(1e18);
int n, m, e[MAXN], v[MAXN], w[MAXN], f[MAXN][1 << 16], ans, pos;
ll V[1 << 16], W[1 << 16], dp[MAXN][1 << 16];
void Print(int x, int y) {
if(!x) {
return;
}
Print(x - 1, y ^ f[x][y]);
cout << __builtin_popcount(f[x][y]) << " ";
for(int i = 1; i <= m; ++i) {
if((f[x][y] >> (i - 1)) & 1) {
cout << i << " ";
}
}
cout << "\n";
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
cin >> e[i];
}
for(int i = 1; i <= m; ++i) {
cin >> v[i] >> w[i];
}
for(int i = 0; i < (1 << m); ++i) {
for(int j = 1; j <= m; ++j) {
V[i] += ((i >> (j - 1)) & 1) * v[j];
W[i] += ((i >> (j - 1)) & 1) * w[j];
}
}
for(int i = 0; i <= n; ++i) {
for(int j = 0; j < (1 << m); ++j) {
dp[i][j] = -INF;
}
}
dp[0][0] = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 0; j < (1 << m); ++j) {
for(int k = j; k >= 1; k = (k - 1) & j) {
if(W[k] <= e[i] && dp[i][j] < dp[i - 1][j ^ k] + V[k]) {
dp[i][j] = dp[i - 1][j ^ k] + V[k];
f[i][j] = k;
}
}
int k = 0;
if(W[k] <= e[i] && dp[i][j] < dp[i - 1][j ^ k] + V[k]) {
dp[i][j] = dp[i - 1][j ^ k] + V[k];
f[i][j] = k;
}
}
}
for(int i = 0; i < (1 << m); ++i) {
if(dp[n][i] > ans) {
ans = dp[n][i], pos = i;
}
}
cout << ans << "\n";
Print(n, pos);
return 0;
}
本文作者:Yaosicheng124
本文链接:https://www.cnblogs.com/yaosicheng124/p/18432882
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步