首页 > 其他分享 >【合集】HZOI2024——冲刺NOIP2024

【合集】HZOI2024——冲刺NOIP2024

时间:2024-03-20 18:14:09浏览次数:32  
标签:int HZOI2024 times read long define 合集 NOIP2024 getchar

前言

喵喵于 \(2024.3.18\) 建立 \(vjudge\) 团队 \(NOIP2024\) ,成员为全体 \(HZOI2024\) 初三现役人员,旗下三个板块的专题训练,分别为动态规划、图论、字符串,其中题目非紫即黑,存在少量蓝。

并于 \(2024.3.19\) 成功关闭 \(luogu\) 。

接下来做的题我会按照开题顺序(大抵等同于从易到难)将 \(A\) 掉的题记录下来,同时可能有类似题的扩展。

动态规划专题

B - Birds

混合背包 \(DP\)

定义 \(f_{i,j}\) 表示取到鸟巢 \(i\) ,获得 \(j\) 只小鸟时所剩的魔力值。

显然有 \(f_{0,0}=1\) 。

转移为:

\[f_{i+1,j+k}=\max(f_{i+1,j+k},\min(f_{i,j}-k\times cost_i+x,w+(j+k)\times b)) \]

其中 \(k\) 表示对于鸟巢 \(i\) 取了几个鸟,其余变量意义与上述表达或题面相同。

特别的,有任意 \(f_{i+1,j+k}\leq w+(j+k)\times b\) ,又题意可得。

注意:

  • 将所有 \(f_{i,j}\) 初始化为 \(-1\) (表示没有更新过,而 \(0\) 可能是恰好为 \(0\) 并非未更新,会产生歧义),若 \(f_{i,j}\) 没有更新过,即他此时所剩魔力值 \(<0\) ,则无法更新 \(f_{i+1,j+k}\) 。

  • 若 \(f_{i,j}-k\times cost_i<0\) 说明无法取这么多鸟,那么显然更大的 \(k\) 也无法取到,所以 \(break\) 。

  • 对于 \(j\) 应循环到 \(sum_i\) ,\(sum_i\) 表示 \(c_i\) 的前缀和,即最多取这么多鸟。

    同理的,\(k\) 循环到 \(c_i\) 。

    当然,\(j,k\) 均从 \(0\) 开始循环。

最后处理答案,显然我们取完鸟巢 \(n\) 后的答案将体现在 \(f_{n+1,j}\) 中,答案为所有 \(\geq 0\) 的 \(f_{n+1,j}\) 中 \(j\) 的最大值。

点击查看代码
#include<bits/stdc++.h>
#define int long long 
#define endl '\n'
using namespace std;
const int N=1e3+10,M=1e4+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int n,w,b,x,ans,c[N],v[N],sum[N],f[N][M];
signed main()
{
	#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    read(n),read(w),read(b),read(x);
    for(int i=1;i<=n;i++) 
        read(c[i]),
        sum[i]=sum[i-1]+c[i];
    for(int i=1;i<=n;i++) read(v[i]);
    memset(f,-1,sizeof(f));
    f[0][0]=w;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=sum[i];j++)
            for(int k=0;k<=c[i];k++)
            {
                int s=f[i][j];
                if(s<0) break;
                s-=k*v[i];
                if(s<0) break;
                s=min(s+x,w+(j+k)*b);
                f[i+1][j+k]=max(f[i+1][j+k],s);
            }
    for(int i=0;i<=sum[n];i++)
        if(f[n+1][i]>=0)
            ans=max(ans,i);
    cout<<ans;
}

I - Game on Sum (Easy Version)

此题为简单版,可以直接跑 \(DP\) 。

定义 \(f_{i,j}\) 表示进行了 \(i\) 轮,其中 \(Bob\) 选择加的有 \(j\) 轮时的分数。

设 \(x_i\) 表示 \(Alice\) 本轮选择的数。

  • 若选择加,则有本轮分数为 \(f_{i-1,j-1}+x_i\) 。

  • 若选择减,则有本轮分数为 \(f_{i-1,j}-x_i\) 。

显然 \(Bob\) 会选择 \(\min(f_{i-1,j-1}+x_i,f_{i-1,j}-x_i)\) 。

已知两者相加为定值,那么显然当两者相等时,\(\min(f_{i-1,j-1}+x_i,f_{i-1,j}-x_i)\) 最大。

所以 \(Alice\) 会选择两者相等时的情况,则有:

\[f_{i,j}=\min(f_{i-1,j-1}+x_i,f_{i-1,j}-x_i)=\dfrac{f_{i-1,j-1}+f_{i-1,j}}{2} \]

同时,显然有 \(f_{i,0}=0\) ,\(f_{i,i}=i\times k\) 。

最后答案为 \(f_{n,m}\) 。

点击查看代码
#include<bits/stdc++.h>
#define int long long 
#define endl '\n'
using namespace std;
const int N=2010,P=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int t,n,m,k,f[N][N],inv2;
int qpow(int a,int b)
{
    int ans=1;
    for(;b;b>>=1)
    {
        if(b&1) (ans*=a)%=P;
        (a*=a)%=P;
    }
    return ans;
}
signed main()
{
	#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    read(t);
    inv2=qpow(2,P-2);
    while(t--)
    {
        read(n),read(m),read(k);
        for(int i=1;i<=n;i++)
            for(int j=0;j<=min(i,m);j++)
                if(i==j) f[i][j]=(k*i)%P;
                else if(j==0) f[i][j]=0;
                else f[i][j]=(((f[i-1][j]+f[i-1][j-1])%P)*inv2)%P;
        cout<<f[n][m]<<endl;
    }
}

Game on Sum (Hard Version)

此题为困难版,将 \(n,m,t\) 的范围都大大增加,无法跑正常的 \(DP\) 。

所以去思考上面所述 \(DP\) 中关于答案的贡献。

不难发现,上述 \(DP\) 可以组成一个类似于杨辉三角的东西。

去考虑 \(f_{i,i}\) 对于答案的贡献,因为只有 \(f_{i,i}\) 在跑 \(DP\) 之前是确定的。

我们发现对于 \(f_{i,j}\) ,他将对 \(f_{i+1,j}\) 与 \(f_{i+1.j+1}\) 产生 \(1\) 的贡献( \(1\) 指 $1\times $ 自身)。

那么以此类推,\(f_{i,i}\) 将对 \(f_{n,m}\) 产生 \(n-i\) 的贡献,其中选择 \(m-i\) 去加。

但同时如果从 \(f_{i,i}\) 去考虑的话,他还会给 \(f_{i+1,i+1}\) 产生 \(1\) 的贡献,但这里已经填好了,显然这一次是不可能给 \(m\) 加的,所以在 \(n-i-1\) 的贡献中选择 \(m-i\) 次去给 \(m\) 加。

也就是 \(f_{i,i}\) 对 \(f_{n,m}\) 的贡献为 \(\dfrac{i\times k\times \text{C}_{n-i-1}^{m-i}}{2^{n-i}}\) 。

这个 \(2^{n-i}\) 显然,每次都是要 \(÷2\) 的,而 \(i\times k\) 表示 \(f_{i,i}\) 自身。

由此最后的答案就为:

\[\sum\limits_{i=1}^{m}\dfrac{i\times k\times \text{C}_{n-i-1}^{m-i}}{2^{n-i}} \]

至于只循环到 \(m\) ,因为 \(Bob\) 只会选择 \(m\) 轮去加。

关于代码:首先需要预处理阶乘与每个 \(2^i\),乘法逆元可用费马小定理 \(+\) 快速幂,因为预处理需要到 \(1e9\) 显然会炸。

点击查看代码
#include<bits/stdc++.h>
#define int long long 
#define endl '\n'
using namespace std;
const int N=1e6+10,P=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int t,n,m,k,jc[N],inv2[N];
int qpow(int a,int b)
{
    int ans=1;
    for(;b;b>>=1)
    {
        if(b&1) (ans*=a)%=P;
        (a*=a)%=P;
    }
    return ans;
}
void pre()
{
    jc[0]=jc[1]=1;
    for(int i=2;i<=N-1;i++) jc[i]=(jc[i-1]*i)%P;
    inv2[0]=1,inv2[1]=2;
    for(int i=2;i<=N-1;i++) inv2[i]=(inv2[i-1]*2)%P;
}
int C(int m,int n)
{
    if(m==0||n==m) return 1;
    return (((jc[n]*qpow(jc[m],P-2))%P)*qpow(jc[n-m],P-2))%P;
}
signed main()
{
	#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    pre();
    read(t);
    while(t--)
    {
        read(n),read(m),read(k);
        if(n==m)
        {
            cout<<(n*k)%P<<endl;
            continue;
        }
        int ans=0;
        for(int i=1;i<=m;i++)
            (ans+=(((((i*k)%P)*C(m-i,n-i-1))%P)*qpow(inv2[n-i],P-2))%P)%=P;
        cout<<ans<<endl;
    }
}

标签:int,HZOI2024,times,read,long,define,合集,NOIP2024,getchar
From: https://www.cnblogs.com/Charlieljk/p/18085793

相关文章

  • 智慧交通三维可视化合集 | 图扑数字孪生
    城市交通作为城市与区域交通体系的核心,其完善程度和发展水平是评价城市现代化水准的关键指标之一。城市交通数字孪生技术正在成为城市交通管理的关键工具,支持系统的高效运行和安全保障。随着互联网、大数据和人工智能技术的进步,城市交通数字孪生应用逐步成熟。图扑软件专注于Web......
  • Hadoop与Spark的x86和ARM混合集群部署【环境搭建篇】
    ​笔者在完成课程设计时,突然想到把大数据框架同时部署到PC端虚拟机以及ARM架构的Linux板上,这篇博客记录集群部署流程以及例程测试。部署架构如下图:若下文与架构图冲突,则以架构图为准。运行环境:PC方面,使用两台Ubuntu20.04LTSFocalFossa虚拟机ARM板子则使用香橙派5(R......
  • 【专题】2024年中国物流地产市场趋势及展望报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=35388原文出处:拓端数据部落公众号2023年,中国物流地产市场在压力之下呈现出波动的复苏态势,市场需求展现出结构性的变化特点。展望未来,物流地产市场将逐渐走向恢复,但不同区域市场之间的表现可能会更加分化。经济的新业态和新动能将为物流地产市场带......
  • 前端面试题合集附答案(问题来源BOOS直聘)
    1,vue的双向绑定原理是什么?里面的关键点在哪里?    1,数据劫持    vue通过Object.defineProperty()方法劫持数据对象属性上的getter和setter,从而实现数据的监听和更新    2,观察者模式    vue采用观察者模式实现对数据的监听和更新,当数据发生变......
  • Java面试问题集合,Java面试题合集
    前言:说到算法,相信每一个程序员和接触过程序员的朋友都不会陌生,直到现在算法一直占着面试必问的地位,而算法面试也仍是当前最适合公司筛选程序员的方法之一,在阿里,字节跳动、华为等公司带动下,无论是求职者还是面试官,都逐渐认识到算法面试其实是相对高效、准确且公平的筛选机制......
  • Python面向对象编程:合集篇(类、对象、封装、继承和多态)
    Python语言设计之初,就是为了面向对象。所以Python的面向对象更加易于理解。如果你以前学过Java、C++你大概就懂得什么是面向对象,但如果你是第一门编程语言就选择Python,那么也不要害怕。这篇文章,我们将会尽量详细的讲解,把Python面向对象编程的知识讲清楚。接下来我们先来简单的......
  • 【论文笔记合集】Transformers in Time Series A Survey综述总结
    本文作者:slience_me文章目录TransformersinTimeSeriesASurvey综述总结1Introduction2Transformer的组成PreliminariesoftheTransformer2.1VanillaTransformer2.2输入编码和位置编码InputEncodingandPositionalEncoding绝对位置编码AbsolutePosit......
  • 【专题】中国智能汽车产业发展与展望报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=34111随着新一轮技术革命和产业变革的推动,以及国家政策的大力扶持,电动化、智能化、网联化已经成为汽车行业发展的新趋势。在这种背景下,各大企业纷纷争夺数字化人才,以推动产品的规模化落地和商业化创新应用。阅读原文,获取专题报告合集全文,解锁文末53......
  • 【专题】2023AIGC人才趋势报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33544自2022年11月ChatGPT发布以来,其超出预期的“涌现”能力彻底点燃了AIGC赛道。从人力资源角度来看,AIGC相关职位数量明显增加,并且人才对于这些职位的投递也更加积极。阅读原文,获取专题报告合集全文,解锁文末190份AIGC行业相关报告。值得注意的是,A......
  • 【专题】2024年中国企业3C数码商用品电商采购白皮书报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=35374原文出处:拓端数据部落公众号近年来,企业电商采购市场呈现稳健增势,主要得益于两方面。首先,企业对采购效率和透明度的要求日益提升,推动了市场的快速发展。其次,对供应商资源整合能力和响应速度的高标准,也进一步促进了市场的繁荣。此外,随着技术的......