首页 > 编程语言 >蓝桥杯第三周算法竞赛D题&&E题

蓝桥杯第三周算法竞赛D题&&E题

时间:2023-11-16 20:48:25浏览次数:36  
标签:gcd int max LL 第三周 蓝桥 && dp define

发现更多计算机知识,欢迎访问Cr不是铬的个人网站

D迷宫逃脱

file
拿到题目一眼应该就能看出是可以用动态规划来解决。但是怎么定义dp呢?

这个题增加难度的点就在当所在位置与下一个要去的位置互质的时候,会消耗一把钥匙。当没有钥匙的时候就不能移动了。想到这里,我们可以定义一个三维的dp数组.

  • 定义dp

dp[i][j][k]表示从位置(1,1)到(i,j)消耗k把钥匙的最大值

  • 初始化

memset(dp,-0x3f3f,sizeof(dp))

dp[i][j][0] = a[1][1]

  • 状态转移方程

dp[i][j][k] = max(dp[i][j][k],dp[i-1][j][k] + a[i][j])

dp[i][j][k] = max(dp[i][j][k],dp[i-1][j][k-1] + a[i][j])互质

dp[i][j][k] = max(dp[i][j][k],dp[i][j-1][k] + a[i][j])

dp[i][j][k] = max(dp[i][j][k],dp[i][j-1][k-1] + a[i][j])互质

  • 输出答案

从dp[n][m][0] ~ dp[n][m][k]找到最大的即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=1e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){
    return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
    return a / gcd(a , b) * b;
}
int main()
{
    //不加不能AC
    //优化输入/输出操作的性能,并精确控制输出的格式
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int n,m,p;
    //读入行宽与高还要钥匙数目
    cin>>n>>m>>p;
    //适当开大一点
    //dp[i][j][k]表示从(1,1)到(i,j)消耗k把钥匙的最大路径和
    LL dp[n+5][m+5][p+5];
    LL a[n+5][m+5];
    for(int i = 1; i <= n;i++)
        for(int j = 1; j <= m;j++)
            cin>>a[i][j];
    //初始化
    memset(dp,-0x3f3f,sizeof(dp));
    dp[1][1][0] = a[1][1];
    for(int i = 1;  i<= n; i++)
        for(int j = 1; j <= m;j++)
            for(int k = 0; k <= p; k++)
            {
                //能够从上转移
                if(i > 1)
                {
                    if(gcd(a[i-1][j],a[i][j]) == 1) {
                        if (k > 0)//不可能出现互质且没消耗一把钥匙的情况
                        { dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k - 1] + a[i][j]); }
                    }
                    else { dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k] + a[i][j]); }
                }
                //能够从左边转移
                if(j > 1)
                {
                    if(gcd(a[i][j-1],a[i][j]) == 1) {
                        if (k > 0)//不可能出现互质且没消耗一把钥匙的情况
                        { dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k - 1] + a[i][j]); }
                    }
                    else { dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k] + a[i][j]); }
                }
            }
    //适当小一点
    LL maxx = -1e18;
    for(int i = 0; i <= p; i++)
        maxx = max(maxx,dp[n][m][i]);
    if(maxx>0)
        cout<<maxx<<endl;
    else
        cout<<-1<<endl;
    return 0;
}

E深秋的苹果

file
这个是一道二分的题目,中规中矩写就行,但是注意此题右端点要开很大!

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=2e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){
    return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
    return a / gcd(a , b) * b;
}
int n,m;
int a[N];
bool check (LL mid)
{
    LL pre = 0, sum = 0,group = 1;//刚开始就是一组
    for(int i = 0;  i < n;i++)
    {
        if(pre + sum * a[i] <= mid)//可以分在一组
        {
            pre += sum*a[i];
            sum += a[i];
        }
        else//新开一组
        {
            group++;
            pre = 0;
            sum = a[i];//这组开始就是a[i]
        }
        if(group > m)return false;
    }
    return true;
}
int main() {

    //优化输入/输出操作的性能,并精确控制输出的格式
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    cin>>n>>m;
    for(int i = 0; i < n;i++)
        cin>>a[i];
    //二分思路
    LL l = 0, r = 3e18;//开大点,防止意外
    while( l < r)
    {
        LL mid = l + (r - l)/ 2; //避免可能的超界
        if(check(mid)) { r = mid; }
        else { l = mid + 1; }
    }
    cout<<l<<endl;

    return 0;
}

本文由博客一文多发平台 OpenWrite 发布!

标签:gcd,int,max,LL,第三周,蓝桥,&&,dp,define
From: https://www.cnblogs.com/xiaocrblog/p/17837210.html

相关文章

  • 蓝桥杯之模拟与枚举day1
    Question1卡片(C/C++A组第一题)这个是一道简单的模拟枚举题目,只要把对应每次的i的各个位都提取出来,然后对应的卡片数目减去1即可。属于打卡题目。注意for循环的特殊使用即可#include<iostream>usingnamespacestd;boolsolve(inta[],intn){//模拟枚举while(n!=0)......
  • 【每日例题】 蓝桥杯 c++ 冶炼金属
    冶炼金属题目小蓝有一个神奇的炉子用于将普通金属О冶炼成为一种特殊金属X。这个炉子有一个称作转换率的属性V,V是一个正整数,这意味着消耗V个普通金属О恰好可以冶炼出一个特殊金属X,当普通金属О的数目不足V时,无法继续冶炼。现在给出了Ⅳ条冶炼记录,每条记录中包含两个整数A和B,这......
  • P9242 [蓝桥杯 2023 E题] 接龙数列
    P9242[蓝桥杯2023E题]接龙数列一眼LIS但是TLE八个点。发现是sb了,应该用string来存数直接取首位末位。改完50分,TLE五个点。换状态\[F_i$$为以数字$i$结尾的最长接龙数列。则顺推每个数字,从每个数字的首位$F_{j_1}+1$以及末位$F_{j_n}$中取最大转移而来。即......
  • 蓝桥杯管道 -- 二分, 区间覆盖
    蓝桥杯管道--二分,区间覆盖原题链接参照执梗大佬的代码,我太菜了wuwuwu......importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importjava.util.Scanner;/***ClassName:Main12*Package:*Description:**@author:LH寒酥......
  • 【每日例题】蓝桥杯 c++ 小郑下五子棋
    小郑下五子棋题目五子棋是—种两人对弈的棋类游戏,它使用黑白两种棋子在一个20×20的棋盘上进行。黑方执黑棋,白方执白棋。双方轮流下棋,目标是先在横向、纵向或斜向连成五个己颜色的棋子,即五子相连,即可获胜。五子棋是—种简单却富有策略的游戏,常常被用于智力训练和竞技比赛。这不,......
  • 【每日例题】蓝桥杯 c++ 被替换的身份证
    被替换的身份证题目蓝桥杯被替换的身份证思路分析斗地主简化版?!废话少说,四种情况ShallowDream一开始出对子或者王炸,ShallowDream胜ShallowDream一开始出单,Joker出王炸,Joker胜ShallowDream一开始出单,Joker手中最大的牌比ShallowDream手中的牌都大,Joker胜ShallowDream一开......
  • 【1111算法题】蓝桥杯 c++(一)第一二题
    【1111算法题】第一题双十一的祈祷【算法赛】题目双十—,不仅是购物狂欢节,更有"光棍节"之称。这源于11:11由四个1构成,象征着单身。作为大学生的小蓝也想经历甜甜的校园恋爱,于是他找到了爱神丘比特,向他祈祷能为自己带来—段邂逅。丘比特是乐于助人的,他承诺小蓝只要回答出一个简......
  • 第十五届蓝桥杯模拟赛 -- 删掉m个字符使得字典序最小
    第十五届蓝桥杯模拟赛--删掉m个字符使得字典序最小贪心+单调栈importjava.util.Deque;importjava.util.LinkedList;importjava.util.Scanner;publicclassMain{ publicstaticvoidmain(String[]args){ Scannerscanner=newScanner(System.in); String......
  • 蓝桥杯2019 估计人数
    蓝桥杯2019估计人数题目描述给定一个\(N\timesM\)的方格矩阵,矩阵中每个方格标记0或者1代表这个方格是不是有人踩过。已知一个人可能从任意方格开始,之后每一步只能向右或者向下走一格。走了若干步之后,这个人可以离开矩阵。这个人经过的方格都会被标记为1,包括开始和结......
  • 【题解 P8763】[蓝桥杯 2021 国 ABC] 异或变换
    同楼上dalao做法:#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<cstdlib>#include<bitset>usingnamespacestd;constintN=1e4+10......