21前两题

news/2024/10/11 16:29:30

廊桥分配

考虑廊桥个数不会影响飞机停靠,所以我们可以将廊桥的个数限制拿掉来看待这个问题。只需要维护一个廊桥的优先队列,然后让飞机每次选取最小的廊桥停靠,如果廊桥有 \(i\) 个,那么到 \(i+1\) 个廊桥就相当于没有停靠到,但是每个廊桥停靠的飞机数目还是一定的。所以我们不妨直接设廊桥个数无限,到了第几个就是做到第几个的前缀和。然后进行模拟,维护一个等待飞走的飞机的优先队列,维护离去的时刻和占用的廊桥,每次弹出离开的,解放廊桥。所以时间复杂度 \(O(n+m+nlogn)\)

#include<bits/stdc++.h>
#define pir pair<int,int>
using namespace std;
const int N=1e5+5;
int n,m1,m2,s1[N],s2[N],maxi;
struct air{int c,l;//come and leave
}a[N],b[N];
void cal(air *q,int m,int *s){priority_queue<pir,vector<pir>,greater<pir> > q1;priority_queue<int,vector<int>,greater<int> > q2;for(int i=1;i<=n;++i) q2.push(i);for(int i=1;i<=m;++i){while(!q1.empty()&&q1.top().first<=q[i].c){//解放廊桥q2.push(q1.top().second); q1.pop();}if(q2.empty()) continue;q1.push(make_pair(q[i].l,q2.top()));s[q2.top()]++;q2.pop();} for(int i=1;i<=n;++i) s[i]+=s[i-1];return;
}
bool cmp(air x,air y){return x.c<y.c;
}
int main(){scanf("%d %d %d",&n,&m1,&m2);for(int i=1;i<=m1;++i) scanf("%d %d",&a[i].c,&a[i].l);sort(a+1,a+m1+1,cmp);for(int i=1;i<=m2;++i) scanf("%d %d",&b[i].c,&b[i].l);sort(b+1,b+m2+1,cmp);cal(a,m1,s1),cal(b,m2,s2);for(int i=0;i<=n;++i) maxi=max(maxi,s1[i]+s2[n-i]);printf("%d",maxi);return 0;
}

括号序列

不考虑枚举 * 而是用来构成合法状态是突破口,设计好的 dp 状态是关键。

为了不算重,我们设计6种状态

0.全为*型

  1. \((……)\) 括号包含型
  2. $ (……)(……)(……)** $
  3. \((……)**(……)**(……)\)
  4. \(**(……)**(……)**(……)\)
  5. \(**(……)**(……)**\)

考虑转移。

​ 0. \(dp_{l,r,0}=dp_{l,r-1,0} \ \&\& (s[r]=='?' \ | \ | \ s[r]=='*')\)。就是继承 \(r-1\)

​ 1.\(dp_{l,r,1}=dp_{l+1,r-1,0}+dp_{l+1,r-1,2}+dp_{l+1,r-1,3}+dp_{l+1,r-1,4}\times ((s[l]=='?' \ | \ | \ s[l]=='(' \ )\&\& (s[r]=='?' \ | \ | \ s[r]==')' \ ) \ )\)。就是如果括号可以匹配,就把括号内的全部包进去统计答案。

​ 2.\(dp_{l,r,2}=\sum\limits_{p=l}^{r-1} dp_{l,p,3}\times dp_{p+1,r,0}\)。因为2显然可以由3和0拼接得来。

​ 3.\(dp_{l,r,3}=\sum\limits_{p=l}^{r-1} (dp_{l,p,3}+dp_{l,p,2})\times dp_{p+1,r,1}+ dp_{l,r,1}\)。首先要明确括号之间不一定非要有*,所以是2、3合起来向3转移。因为3包含1,所以要加上这个区间1可能的答案,注意是枚举完了才累加。

​ 4.\(dp_{l,r,4}=\sum\limits_{p=l}^{r-1} (dp_{l,p,4}+dp_{l,p,5})\times dp_{p+1,r,1}\)。同理,不过这个转移也可以是 \(dp_{l,p,0}\times dp_{p+1,r,3}\)

​ 5.\(dp_{l,r,5}=\sum\limits_{p=l}^{r-1} dp_{l,p,4}\times dp_{p+1,r,0}+dp_{l,r,0}\)。5可由4、0拼接而来,然后0也属于5。

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,k;
char s[505];
long long dp[505][505][7];
int read(){char ch;int x=0,f=1;while(!isdigit(ch=getchar())){if(ch=='-') f=-1;}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch-'0');ch=getchar();}return x*f;
}
int main(){freopen("bracket.in","r",stdin);freopen("bracket.out","w",stdout);n=read(),k=read();scanf("%s",s+1);for(int i=1;i<=n;++i) dp[i][i-1][0]=1;for(int len=1;len<=n;++len){for(int l=1;l+len-1<=n;++l){int r=l+len-1;if(len<=k) dp[l][r][0]=dp[l][r-1][0]&&(s[r]=='*'||s[r]=='?');if((s[l]=='?'||s[l]=='(')&&(s[r]=='?'||s[r]==')')) dp[l][r][1]=(dp[l+1][r-1][0]+dp[l+1][r-1][2]+dp[l+1][r-1][3]+dp[l+1][r-1][4])%mod;if(len>=2){for(int p=l;p<r;++p){dp[l][r][2]=(dp[l][r][2]+dp[l][p][3]*dp[p+1][r][0]%mod)%mod;dp[l][r][3]=(dp[l][r][3]+(dp[l][p][3]+dp[l][p][2])*dp[p+1][r][1]%mod)%mod;dp[l][r][4]=(dp[l][r][4]+(dp[l][p][4]+dp[l][p][5])*dp[p+1][r][1]%mod)%mod;dp[l][r][5]=(dp[l][r][5]+dp[l][p][4]*dp[p+1][r][0]%mod)%mod;}}dp[l][r][5]=(dp[l][r][5]+dp[l][r][0])%mod;dp[l][r][3]=(dp[l][r][1]+dp[l][r][3])%mod;}}
//	for(int len=1;len<=n;++len){
//		for(int l=1;l+len-1<=n;++l){
//			int r=l+len-1;
//			printf("%d %d %lld/%lld/%lld/%lld/%lld/%lld  ",l,r,dp[l][r][0],dp[l][r][1],dp[l][r][2],dp[l][r][3],dp[l][r][4],dp[l][r][5]);
//		}
//		printf("\n");
//	}printf("%lld",dp[1][n][3]);return 0;
} 

报数

筛法,注意卡常和范围。

数列

这个题还是比较难的。难点在于想到 \(S\) 的位数和 \(\{a_i\}\)的关系其实是二进制填数,而对于 \(S\) 的每一位都可以通过有多少个 \({a_i}\) 来构成唯一确定的状态。

总而言之,设计状态难。

我的思路历程是想到了 \(S\)\(\{a_i\}\) 之间一一对应的关系,但是没有想到枚举当前位可能有多少个 \(\{a_i\}\)。这启示我以后要抓住题目的性质,持续深入地想问题。dp状态的设计要清晰确定可转移,还要满足子结构。dp的状态就是一个明确的语句,表达的意思就是你对题目答案是如何组成的理解。

\(dp_{i,j,s,t}\) 表示当前考虑到 \(S\) 的第 \(i\) 位,\(a\) 中我们已经确定了几个元素(注意,这里确定了几个元素是相对于 \(S\) 枚举到了第几位而言的,每多枚举一位都有可能让其不一样,而我们枚举的只是确定了几个元素,因为序列是无序的,我们不能说到了第 \(j\) 个元素,这是一种相对关系),到这一位为止有多少个 1 (为什么会想到这个呢?首先是因为题目中有1的个数的限制,其次是我们要确定这一个才能确定每一位的值,才能让 \(S\) 维持一个二进制数的性质,不然就成了什么十进制之类的数了,那样显然不利于解决问题,所以这一维对于我们确定当前处于什么阶段和状态的转移是不可缺少的),这一位向下一位进多少个1(这个和上一维同理)。

我们解决了状态的设计,那么转移方程式就清晰可见了。由于我们不好确定\(i-1\)位的状态,所以我们直接向下一位转移:

\[{\large dp_{i+1,j+p,s+(t+p)\%1,\lfloor \frac{(t+p)}{2} \rfloor}=\sum\limits_{p=0}^{n-j} dp_{i,j,s,t}\times v_{a_i}^p\times \binom{n-j}{p}} \]

我当前位可能有多个1,所以我要枚举有多少个,所以我就多确定了这么多个。有多少一就是上一位有多少一加上上一位的进位加上这一位新加了多少 \(\%2\),向前进同理。

注意范围和预处理。

注意到了\(m\)位有可能还是多个1,所以不能直接在\(m\)位统计答案,要向后面进位一下才可以。

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n,m,k;
long long dp[105][35][35][17],C[105][35],pv[105][35],v[105],ans;
int main(){freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);scanf("%d %d %d",&n,&m,&k);for(int i=0;i<=m;++i) scanf("%lld",&v[i]);for(int i=0;i<=m;++i){pv[i][0]=1;for(int j=1;j<=n;++j) pv[i][j]=pv[i][j-1]*v[i]%mod; }for(int i=0;i<=n;i++) C[i][0]=1;for(int i=1;i<=n;i++)for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;dp[0][0][0][0]=1;for(int i=0;i<=m;++i){for(int j=0;j<=n;++j){for(int s=0;s<=k;++s){for(int t=0;t<=n>>1;++t){for(int p=0;p<=n-j;++p){dp[i+1][j+p][s+((t+p)&1)][(t+p)>>1]=(dp[i+1][j+p][s+((t+p)&1)][(t+p)>>1]+(dp[i][j][s][t]*pv[i][p]%mod)*C[n-j][p]%mod)%mod;}}}}}for(int s=0;s<=k;++s){for(int t=0;t<=n>>1;++t){if(s+__builtin_popcount(t)<=k) ans+=dp[m+1][n][s][t],ans%=mod;}}printf("%lld\n",ans);return 0;
}

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

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

相关文章

Small Permutation Problem (Easy Version)

算法 考虑转化 每个点 \(p_i\) 在一个平面直角坐标系中表示为点 \((i, p_i)\) 于是转化为一个棋盘问题, 即每一个点不能在 同一行 / 同一列 \(a\) 数组的限制相当于在左下角为 \((0, 0)\), 右上角为\((i, i)\) 中的正方形中, 有 \(a_i\) 个棋子 于是在每一次加入的时候, 都只能…

Flutter功能性组件(2):弹出框

一、showModalBottomSheet(模态底部弹出框) showModalBottomSheet 用于显示一个模态底部弹出框。 属性解析: Future<T?> showModalBottomSheet<T>({required BuildContext context, // 表示底部弹出框所处的上下文,通常来自当前 widget。required WidgetBuild…

Flutter容器(6):页面骨架(Scaffold)

Material 组件库提供了丰富多样的组件,这里介绍一下最常用的 Scaffold 组件,其余的读者可以自行查看文档或 Flutter Gallery 中 Material 组件部分的示例。注意:Flutter Gallery 是 Flutter 官方提供的 Flutter Demo,源码位于 flutter 源码中的 examples 目录下,笔者强烈建…

Golang上下文context

上篇内容我们主要讲解了net/http标准库的使用,其中包含如何创建POST请求、GET请求以及如何携带参数的请求。 Context介绍 context释义为上下文,在我们使用goroutine时一般使用context来进行元数据的传递,非元数据不建议使用context来进行传递。那么我们主要是用context用来做…

2024 最新 IntelliJ IDEA 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 IDEA 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!2.…

淘宝程序员没活硬整?在 Excel 和 VSCode 中购物!

你可以在 Excel 表格中挑选商品进行购物,还原度极高,这两个图表更是点睛之笔。哪个天才想出来的,把特么广告都整成了 Excel 图表。大家好,我是程序员鱼皮,最近某宝网站的改进,属实是有点 “新” 了。 你敢相信这是一个购物网站么?你可以在 Excel 表格中挑选商品进行购物…

Golang模板template

背景概述 当我们在进行json字段选取以及渲染时,我们经常会见到{{}},其实这就是我们今天要讲解的模板即是template。例如prometheusAlert中的模板就是使用了改语法。 必备技能字段选取 ❝ {{ . }} 表示json的所有域,例如:{"name":"anruo","age&quo…

如何在springboot中,全局配置produces=text/plain;charset=UTF-8

为什么要使用produces="text/plain;charset=UTF-8"? 当不用这个配置时,接口返回的数据,是有斜杠的 配置后,就正常了 以前我的配置方式,是在每个接口上,都添加上produces="text/plain;charset=UTF-8"。但是这样显示不太好,每个接口都加的话,会比较…