日常刷题2025-2-17

日常刷题2025-2-17

建筑入门

rating:68 / 1279

https://ac.nowcoder.com/acm/contest/101921/E

思路:完全背包+构造

https://www.bilibili.com/video/BV1utKKe6EY9?spm_id_from=333.788.videopod.episodes&vd_source=4a339d299e165d8fe38b9926c5240eae&p=5

评述

题目的思维转换非常巧妙,完全想不到会是一道完全背包。

代码

#include <bits/stdc++.h>
using u64 = unsigned long long;
using i64 = long long;
typedef std::pair<int, int> pii;
const int mod = 998244353;
const long long LINF = 1e18;
void solve(){
int n, k;
std::cin >> n >> k;
for (int i = 1; i <= n; i++){
k -= i * i;
}
if (k < 0) {
std::cout << "-1\n";
return;
}
std::vector<int> a(n+2);
for (int i = n; i >= 1; i--){
a[i] = a[i+1] + i;
}
std::vector<int> dp(k+1);
std::vector<pii> path(k+1);
dp[0] = 1;
for (int i = 1; i <= n; i++){
for (int j = a[i]; j <= k; j++){
if (dp[j-a[i]] && !dp[j]){
dp[j] = 1;
path[j] = {j - a[i], i};
}
}
}
if (!dp[k]){
std::cout << "-1\n";
return;
}
std::vector<int> nums;
int cur = k;
while (cur > 0){
auto [pre, x] = path[cur];
nums.emplace_back(x);
cur = pre;
}
std::vector<int> ans(n+1);
for (auto idx : nums){
ans[idx]++;
}
for (int i = 1; i <= n; i++){
ans[i] += ans[i-1];
}
for (int i = 1; i <= n; i++){
ans[i] += i;
std::cout << ans[i] << ' ';
}
std::cout << '\n';
}
signed main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15);
int t = 1, i;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

猪猪养成计划2

rating:271 / 696

https://ac.nowcoder.com/acm/contest/99785/D

思路:分组背包

基本上一眼DP题,不过状态定义有点麻烦,一般来说,简单的DP定义都是题目问什么就定义什么,但是这题不同。如果思考每只猪是选择陪伴还是花钱的话,状态定义不下去。我们想看到的选与不选没有出现,有一个思维转换是我们最坏的情况下是每只猪都花钱,那么我们能得到一个花钱的最大值,在这个基础上在考虑哪只猪陪伴,这样题目就转换成了我们希望看到的选与不选了。

代码

#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
typedef std::pair<long long, long long> PII;
const int mod = 998244353;
const int N = 2e6 + 1000;
const int INF = 0x3f3f3f3f;
const long long LINF = 1e18;
const double eps = 1e-12;
const double pi = std::acos(-1);
std::mt19937_64 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
std::uniform_int_distribution<u64> dist_rand(mod / 2, mod - 1);
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<std::array<i64, 3>> a(n + 1);
std::vector<std::vector<PII>> pos(n + 2);
i64 res = 0;
for (int i = 1; i <= n; i ++) std::cin >> a[i][0];
for (int i = 1; i <= n; i ++) std::cin >> a[i][1] >> a[i][2], res += a[i][2];
for (int i = 1; i <= n; i ++) pos[a[i][0]].emplace_back(a[i][1], a[i][2]);
std::vector<i64> dp(n + 2, LINF);
dp[0] = 0;
for (int i = 0; i <= n; i ++) {
for (auto [b, val] : pos[i]) dp[i + m] = std::min(dp[i + m], dp[i] - val + b);
dp[i + 1] = std::min(dp[i + 1], dp[i]);
}
std::cout << res + dp[n + 1] << "\n";
}
signed main() {
std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int tmp = 1;
// std::cin >> tmp;
while (tmp--)
solve();
return 0;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18719694

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

posted @   califeee  阅读(1)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.