【比赛】高一高考集训总结赛

news/2024/10/5 11:14:28

一场比赛四道 DP
乐了
集训全学 DP 你还真给我全考 DP 啊

T1 乌龟棋 70 Pts

题面

\(f_{i,j,k,w}\) 表示已经翻开 \(i\) 张步数为 \(1\) 的牌,\(j\) 张步数为 \(2\) 的牌,以此类推,暴力 DP 即可。
但赛时先开了个五维 DP 数组,然后发现开不下;
正常人到这就会想到要压掉一位了,但我直接用 滚动数组 强行开下了。
然后就 $\text{TLE} \to 70 $

点击查看代码
#include<bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=355;
int f[45][45][45][45];
int n,m,x;
int a[N],c[10];
inline int read(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x;
}
int main(){freopen("a.in","r",stdin); freopen("a.out","w",stdout); n=read();m=read();for(int i=1;i<=n;i++)a[i]=read();for(int i=1;i<=m;i++)c[read()]++;f[0][0][0][0]=a[1];for(int i1=0;i1<=c[1];i1++){for(int i2=0;i2<=c[2];i2++){for(int i3=0;i3<=c[3];i3++){for(int i4=0;i4<=c[4];i4++){int now=1+i1+i2*2+i3*3+i4*4;int &v=f[i1][i2][i3][i4];if(i1!=0)v=max(v,f[i1-1][i2][i3][i4]+a[now]);if(i2!=0)v=max(v,f[i1][i2-1][i3][i4]+a[now]);if(i3!=0)v=max(v,f[i1][i2][i3-1][i4]+a[now]);if(i4!=0)v=max(v,f[i1][i2][i3][i4-1]+a[now]);}}}}cout<<f[c[1]][c[2]][c[3]][c[4]];return 0;
}

T2 划分大理石 100Pts

题面

多重背包,二进制拆分。
数据过水导致很多乱搞做法可以通过。

赛后这题被加了 \(6\) 组测试数据。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=20005;
int a[7],sum;
int w[N],f[N],cnt;
int main(){freopen("b.in","r",stdin);freopen("b.out","w",stdout);while(1){scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6]);sum=a[1]+a[2]*2+a[3]*3+a[4]*4+a[5]*5+a[6]*6;if(!sum)break;if((sum&1)){puts("Can't");continue;}sum/=2;f[0]=1;for(int i=1;i<=6;i++){int tmp=a[i],j=1;while(tmp>j){tmp-=j;w[++cnt]=j*i;j<<=1;}if(tmp)w[++cnt]=tmp;}for(int i=1;i<=cnt;i++){for(int j=sum;j>=w[i];j--){f[j]=(f[j]||f[j-w[i]]);}}if(f[sum])puts("Can");else puts("Can't");}return 0;
}

T3 干草堆 47Pts

题面

神仙斜率优化 DP,反正我没想出来。

倒序输入和处理,设 \(sum_i\) 表示前 \(i\) 块的前缀和,\(f_i\) 表示处理到第 \(i\) 块时的最大高度,\(g_i\) 表示处理到第 \(i\) 块时的最小宽度,有转移方程:

\[f_i=f_{j+1}+1 \]

\[g_i=sum_i-sum_{j+1} \]

其中 \(j\) 为从 \(i\)\(n\) 中最小的使得 \(g_{j+1} \le sum_i-sum_{k+1}\)\(j\)

由于数据过水,这个 \(O(n^2)\) 的代码已经可以 A 了。
但我们可以使用单调栈维护这个式子,将复杂度降至 \(O(n)\)

赛时先打了贪心做法,小样例直接过,大样例直接死,发现贪心假了;
然后死活想不出来 DP 状态怎么设计,然后测试点分治 贪心 + 爆搜;
然后分治出了点小锅,T 了一个点 ,\(53 \to 47\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int f[N],w[N],sum[N],g[N];
int n;
int q[N],l=1,r=0;
int main(){freopen("c.in","r",stdin);freopen("c.out","w",stdout);cin>>n;for(int i=n;i;i--){cin>>w[i];}for(int i=1;i<=n;i++){sum[i]=sum[i-1]+w[i];}q[++r]=0;for(int i=1;i<=n;i++){while(l<r&&sum[q[l+1]]+g[q[l+1]]<=sum[i])l++;f[i]=f[q[l]]+1;g[i]=sum[i]-sum[q[l]];while(l<r&&sum[q[r]]+g[q[r]]>=sum[i]+g[i])r--;q[++r]=i;}cout<<f[n];return 0;
}

T4 围栏障碍训练场 100Pts

题面

数据结构优化 DP。

\(f_{i,0}\) 表示到第 \(i\) 条栅栏后从左边走的最小值,\(f_{i,1}\) 表示从右边走的最大值。
\(l_i\) 表示栅栏 \(i\) 的左端点,\(r_i\) 表示右端点,则有转移方程:

\[\begin{gather*}f_{j,0}=f_{i,0}+|l_i-l_j|\\f_{j,1}=f_{i,0}+|r_j-l_i|\\f_{k,0}=f_{i,1}+|r_i-l_k|\\f_{k,1}=f_{i,1}+|r_k-r_i| \end{gather*} \]

其中,\(j\)\(i+1\)\(n\) 中满足 \(l_j<l_i<r_j\) 的第一个 \(j\)\(k\) 为满足 \(l_k<r_i<r_k\) 的第一个 \(k\)

然后数据水了,\(O(n^2)\) 的暴力过了。
但是这题 \(n\) 只有 \(3 \times 10^4\),卡不掉 \(n^2\)
所以没补正解。整洁转自涛哥。

$O(n^2)$
#include<bits/stdc++.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
using namespace std;
typedef long long ll;
const int N=3e4+5;
int f[N][2],n,s;
int l[N],r[N];
int ans=INT_MAX;
int main(){freopen("d.in","r",stdin);freopen("d.out","w",stdout);scanf("%d%d",&n,&s);for(int i=n;i;i--)scanf("%d%d",&l[i],&r[i]);memset(f,0x3f,sizeof(f));f[1][0]=s-l[1],f[1][1]=r[1]-s;for(int i=1;i<=n;i++){if(f[i][0]==0x3f3f3f3f&&f[i][1]==0x3f3f3f3f)continue;int a=l[i],b=r[i];bool fa=0,fb=0;for(int j=i+1;j<=n;j++){if(fa==1&&fb==1)break;if(l[j]<a&&a<r[j]&&(!fa)){f[j][0]=min(f[j][0],f[i][0]+a-l[j]);f[j][1]=min(f[j][1],f[i][0]+r[j]-a);fa=1;}if(l[j]<b&&b<r[j]&&(!fb)){f[j][0]=min(f[j][0],f[i][1]+b-l[j]);f[j][1]=min(f[j][1],f[i][1]+r[j]-b);fb=1;}}if(!fa)ans=min(ans,f[i][0]+abs(a));if(!fb)ans=min(ans,f[i][1]+abs(b));}printf("%d",ans);return 0;
}
正解
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,s,a[N],b[N],res[N][2];
int t[N<<3];
inline void pushdown(int x)
{if(t[x]){t[x<<1]=t[x<<1|1]=t[x];t[x]=0;}return ;
}
inline void change(int x,int l,int r,int ql,int qr,int q)
{if(ql<=l&&r<=qr){t[x]=q;return ;}pushdown(x);int mid=l+r>>1;if(ql<=mid)change(x<<1,l,mid,ql,qr,q);if(qr>mid)change(x<<1|1,mid+1,r,ql,qr,q);return ;
}
inline int query(int x,int l,int r,int q)
{if(l==r)return t[x];pushdown(x);int mid=l+r>>1;if(q<=mid)return query(x<<1,l,mid,q);return query(x<<1|1,mid+1,r,q);
}
int main()
{freopen("d.in","r",stdin);freopen("d.out","w",stdout);cin>>n>>s;for(int i=1;i<=n;i++)cin>>a[i]>>b[i];for(int i=1,q;i<=n;i++){q=query(1,-N,N,a[i]);res[i][0]=min(res[q][0]+abs(a[i]-a[q]),res[q][1]+abs(b[q]-a[i]));q=query(1,-N,N,b[i]);res[i][1]=min(res[q][0]+abs(b[i]-a[q]),res[q][1]+abs(b[q]-b[i]));change(1,-N,N,a[i],b[i],i);}cout<<min(res[n][0]+abs(a[n]-s),res[n][1]+abs(b[n]-s));return 0;
}

后记

  • 很水的一场比赛,但是是数据水。

  • T2 没说多测组数,然后 wwppcc 和 GGrun 放了个大点上去把除了单调队列优化 DP 外的所有做法全部卡 T 了。

  • 赛时 Qyun 和 HDK 的电脑炸掉了,但 Qyun 顶着这个 Debuff 砍了 190Pts,%

  • 总结:题目排版总有一个是史。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/44026.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

O(1)LCA

大家常用的三种LCA算法如下: 倍增为在线,复杂度\(\Theta(n\log n)\)预处理,\(\Theta(\log n)\)查询。 树剖为在线,复杂度\(\Theta(n)\)预处理,\(\Theta(\log n)\)查询。 Tarjan为离线,\(\Theta(n+q)\)复杂度。 现在介绍\(\Theta(n\log n)\)时间预处理,\(\Theta(1)\)查询…

CMU15445数据库系统笔记.18221501

本篇文章是CMU 15445数据库系统的学习笔记,持续更新... [课程视频 Fall 2021] | [课程主页]LEC03. 数据库存储结构(上) 分层设计概述 设计任何大型系统时的一个常用手段是分层,数据库系统也可以被分成若干层,每一层处理自己的事情,向上提供简单的API隐藏细节。举个例子,…

纪念一下

教程来自:2019ISCC_web题解 - oswords blog (zhzhdoai.github.io)

2024-06-15:用go语言,Alice 和 Bob 在一个环形草地上玩一个回合制游戏。 草地上分布着一些鲜花,其中 Alice 到 Bob 之间顺时针方向有 x 朵鲜花,逆时针方向有 y 朵鲜花

2024-06-15:用go语言,Alice 和 Bob 在一个环形草地上玩一个回合制游戏。 草地上分布着一些鲜花,其中 Alice 到 Bob 之间顺时针方向有 x 朵鲜花,逆时针方向有 y 朵鲜花。 游戏规则如下: 1.游戏从 Alice 开始。 2.每个回合中,当前玩家必须选择顺时针或逆时针,并在所选方向…

网上购物

创建数据库 安装Navicat Premium 到Navicat官网上下载,链接:https://www.navicat.com.cn/ 安装好后,通过相关命名创建数据库。 第一步:创建数据库 CREATE DATABASE 数据库名 CHARACTER SET utf8; 第二步:创建数据库表 如果之前有相同的数据库表,可以执行下面的命名删除数…

农业气象综合监测站:农业智能化革命的强力助推器

科技之光正在点亮农业领域,引领其迈向智能化的新纪元。其中,农业气象综合监测站无疑成为这场革命中的璀璨明星,它以强大的功能深度剖析气象条件与农业生产间的紧密联系,为农业生产提供精准的决策支持,从而大幅提升生产效率和安全性。农业气象综合监测站的核心职责在于实时…

数据读写流程

数据读写流程 在bitcast论文中,想要获取内存中存储的数据,我们首先得获取索引数据,在索引数据中获取到文件id以及数据存储所在位置,然后根据这些信息去读取文件内容。 所有我们在进行写数据时也得有两步,第一步将key value信息持久化到文件中,第二部是将索引信息保存到内…

第二章节C代码RUST实现

第二章节书中代码有如下内容这些C语言代码大致实现了一个简单版的 who 命令。这个命令的功能是读取系统的 utmp 文件,并显示当前登录的用户信息。utmp 文件包含关于用户登录会话的信息,包括用户名、登录终端、登录时间等。以下是对上述所有代码实现功能的总结:cp1:实现复制文…