随笔 - 164  文章 - 0  评论 - 4  阅读 - 9882

2023牛客多校第五场 - D G H

比赛地址:传送门
赛时过了 3 题,后期坐大牢!
G 尺取法双指针
H 动态规划,背包DP

D Cirno's Perfect Equation Class

题意
给定 k,c,n,求正数对 (a,b) 的个数满足 ka+b=c,b|c(c=bx,x1),gcd(a,b)n

思路
不难发现 b 是 c 的因子,所以枚举 b,判断相应的 a 是否满足条件即可

代码

void solve(){
int k, c, n;
cin >> k >> c >> n;
vector<int> s;
for(int i = 1; i * i <= c; ++ i){
if(c % i == 0){
s.push_back(i);
if(i * i != c) s.push_back(c / i);
}
}
sort(s.begin(), s.end());
int ans = 0;
for(auto b : s){
int a = (c - b) / k;
if(a * k == c - b && a > 0 && __gcd(a, b) >= n) ++ ans;
}
cout << ans << '\n';
return ;
}

G Go to Play Maimai DX

题意
给定长为 n 的数组和数 k ,数组中每个数均[1,4],需要找到最小的区间,包含至少一个数字 1,2,3,包含 k 个 4。

思路
尺取法即可

代码

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long
using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
*/
const int maxm = 1e5 + 5, inf = 0x3f3f3f3f, mod = 998244353;
int n, k, a[maxm], c[5];
void solve(){
cin >> n >> k;
for(int i = 0; i < n; ++ i){
cin >> a[i];
}
int l = 0, r = 0, lei = 0, ans = n + 1;
while(r < n){
while(lei <= 4 && r < n){
++ c[a[r]];
if(c[a[r]] == 1) ++ lei;
++ r;
if(c[4] >= k && lei == 4) break;
}
-- r;
if(lei < 4 || c[4] < k) break;
while(c[a[l]] > 1 && a[l] != 4 || c[a[l]] > k && a[l] == 4){
-- c[a[l]];
++ l;
}
ans = min(ans, r - l + 1);
-- c[a[l]];
if(c[a[l]] == 0) -- lei;
++ l;
++ r;
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_ --){
solve();
}
return 0;
}

H Nazrin the Greeeeeedy Mouse

题意
详见题面
There're n cheeses in the house. The ith cheese is between point i and point i+1 . The ith cheese's size is ai and its weight is bi.
Nazrin is at point 1 in the beginning and wants to steal some cheeses. She has m chances to take the cheeses:
In the ith time, Nazrin brings a bag of size szi . Since she's greedy, for i>1,szi>szi1 always holds. She can travel from point 1 and take some cheeses. She can only travel from point x to x+1, or backwards. If she wants to travel from point x to point x+1, she has to dig a hole on the xth cheese or take it. She can't take a cheese with a hole on it. Of course, the sum of the cheeses' size she takes in the ith time can't be larger than szi. After taking the cheeses, she needs to go back to point 1.
Please maximize the sum of the weights of taken cheeses and output it.
1n200,1m105,1ai200,1bi105,1szi200

思路
没那么简单的01背包DP,多个01相互牵制背包DP取最优
有个小提示就是当 n<m 时,我们可以仅用后 n 个背包即可。从前往后遍历物品,对于每一个背包都做背包DP,那么我们就可以获得对于所有背包自己的最大值,之后我们再进行一步操作,就是将前一个背包的最大值转移到后一个背包的 0 空间上去,因为最终的最大如果不在单个背包上取,那就在多个背包共同取,而后一个背包取需要在前一个背包的基础上取!
理解的还不是很透彻,详见代码。。。

代码

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long
using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
*/
const int maxm = 2e2 + 5, inf = 0x3f3f3f3f, mod = 998244353;
void solve(){
int n, m;
cin >> n >> m;
vector<int> a(n), b(n), h(m);
for(int i = 0; i < n; ++ i){
cin >> a[i] >> b[i];
}
for(int c = 0; c < m; ++ c){
cin >> h[c];
}
if(m > n){
h.erase(h.begin(), h.end() - n);
m = n;
}
vector<vector<int>> dp(m, vector<int>(maxm, 0));
for(int i = 0; i < n; ++ i){ // i 个物品
for(int j = 0; j < m; ++ j){ //每个包
for(int k = h[j]; k >= a[i]; --k){
dp[j][k] = max(dp[j][k], dp[j][k - a[i]] + b[i]);
}
}
for(int j = 0; j < m - 1; ++ j){ //将前面的最优状态转到下一背包的 0 空间状态
for(int k = 0; k <= h[j]; ++ k){
dp[j + 1][0] = max(dp[j + 1][0], dp[j][k]);
}
}
}
int ans = 0;
for(int i = 0; i <= h[m - 1]; ++ i){ //最终的答案即为最后一背包的最大值
ans = max(ans, dp[m - 1][i]);
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_ --){
solve();
}
return 0;
}
posted on   Qiansui  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示