CSP-S模拟37

news/2025/10/24 22:13:02/文章来源:https://www.cnblogs.com/countryhuman/p/19164327

T1:回文(string)

思路:

由于本题的数据范围较小,所以可能有多种 \(dp\) 状态,这里只呈现其中可能较典的两种外加一种暴搜最优解。

DP1:

我们设 \(f_{i,j,x,y}\) 表示使用 \(a\) 串的 \(i\) ~ \(j\)\(b\) 串的 \(x\) ~ \(y\) 能否拼成一个回文串。

首先考虑原始状态是什么样的。显然原始状态有三种大情况: \(a,b\) 中的单个字符,\(a,b\) 中相邻的两个相同的字符以及 \(a,b\) 串中相同的字符。这些显然都是初始能构成回文串的字符。

然后再考虑转移。显然有四种转移方式:\(a\) 串自己左右扩展, \(b\) 串自己左右扩展, \(a\) 串左端与 \(b\) 串右端匹配, \(a\) 串右端与 \(b\) 串左端匹配。

最后我们枚举每个串截取的长度,然后枚举起点,计算出终点。若 \(f_{i,j,x,y}\)\(1\) ,则 \(ans=max(ans,lena+lenb)\)

\(O(Tn^4)\) 的时间复杂度。跑得还是比较快的。

代码:

$code$
#include<iostream>
#include<cstring>
using namespace std;
int T,n,m,ans,f[55][55][55][55];
string a,b;
int main(){freopen("string.in","r",stdin);freopen("string.out","w",stdout);ios::sync_with_stdio(false);cin>>T;while(T--){ans=1;memset(f,0,sizeof(f));cin>>a>>b;a=' '+a;b=' '+b;n=a.size()-1;m=b.size()-1;for(int i=1;i<=n;i++) for(int j=1;j<=m+1;j++) f[i][i][j][j-1]=1;for(int j=1;j<=m;j++) for(int i=1;i<=n+1;i++) f[i][i-1][j][j]=1;for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i]==b[j]) f[i][i][j][j]=1;for(int i=1;i<n;i++){if(a[i]==a[i+1]){for(int j=1;j<=m+1;j++){ans=2;f[i][i+1][j][j-1]=1;}}}for(int j=1;j<m;j++){if(b[j]==b[j+1]){for(int i=1;i<=n+1;i++){ans=2;f[i][i-1][j][j+1]=1;}}}for(int lena=0;lena<=n;lena++){for(int i=1;i<=n-lena+1;i++){int j=i+lena-1;for(int lenb=0;lenb<=m;lenb++){for(int x=1;x<=m-lenb+1;x++){int y=x+lenb-1;if(f[i][j][x][y]){ans=max(ans,lena+lenb);if(i>1&&j<n&&a[i-1]==a[j+1]) f[i-1][j+1][x][y]=1;if(x>1&&y<m&&b[x-1]==b[y+1]) f[i][j][x-1][y+1]=1;if(i>1&&y<m&&a[i-1]==b[y+1]) f[i-1][j][x][y+1]=1;if(x>1&&j<n&&a[j+1]==b[x-1]) f[i][j+1][x-1][y]=1;}}}}}cout<<ans<<'\n';}return 0;
}//题解方法 (较快) 

DP2:

我们设 \(f_{i,j,x,y}\) 表示使用 \(a\) 串的 \(i\) ~ \(j\)\(b\) 串的 \(x\) ~ \(y\) 能拼成回文串的最长长度。

还是先考虑初始状态,显然跟上面的是一样的,不过上述的状态一初始值为 \(1\) ,状态二、三的初始值为 \(2\) (因为存的是长度嘛)

然后转移就是正常的转移了。不过记得特判一下把单个字符放到另一个串里的情况喔~~

最后取 \(max\) 就好啦~~

时间复杂度也是 \(O(Tn^4)\) 的,不过或许是因为大力分讨,跑起来不如上面那个快。

$code$
#include<iostream>
#include<cstring>
using namespace std;
int T,m,n,ans,f[55][55][55][55];
string a,b;
int main(){
//	freopen("string.in","r",stdin);
//	freopen("string.out","w",stdout);ios::sync_with_stdio(false);cin>>T;while(T--){memset(f,0,sizeof(f));cin>>a>>b;a=' '+a;b=' '+b;n=a.size()-1;m=b.size()-1;for(int lena=0;lena<=n;lena++){for(int i=1;i<=n-lena+1;i++){int j=i+lena-1;for(int lenb=0;lenb<=m;lenb++){for(int x=1;x<=m-lenb+1;x++){int y=x+lenb-1;if(lena+lenb==1) f[i][j][x][y]=1;if(lena+lenb==2){if(!lena&&b[x]==b[y]) f[i][j][x][y]=2;else if(!lenb&&a[i]==a[j]) f[i][j][x][y]=2;else if(lena&&lenb&&a[i]==b[x]) f[i][j][x][y]=2;}if(lena+lenb!=f[i][j][x][y]) continue;if(i>1&&j<n&&a[i-1]==a[j+1]) f[i-1][j+1][x][y]=max(f[i-1][j+1][x][y],f[i][j][x][y]+2);if(x>1&&y<m&&b[x-1]==b[y+1]) f[i][j][x-1][y+1]=max(f[i][j][x-1][y+1],f[i][j][x][y]+2);if(i>1&&y<m&&a[i-1]==b[y+1]) f[i-1][j][x][y+1]=max(f[i-1][j][x][y+1],f[i][j][x][y]+2);if(x>1&&j<n&&b[x-1]==a[j+1]) f[i][j+1][x-1][y]=max(f[i][j+1][x-1][y],f[i][j][x][y]+2);if(!lena&&y<m&&a[i]==b[y+1]) f[i][i][x][y+1]=max(f[i][i][x][y+1],f[i][j][x][y]+2);if(!lena&&x>1&&a[i]==b[x-1]) f[i][i][x-1][y]=max(f[i][i][x-1][y],f[i][j][x][y]+2);if(!lenb&&j<n&&b[x]==a[j+1]) f[i][j+1][x][x]=max(f[i][j+1][x][x],f[i][j][x][y]+2);if(!lenb&&i>1&&b[x]==a[i-1]) f[i-1][j][x][x]=max(f[i-1][j][x][x],f[i][j][x][y]+2);}}}}int ans=0;for(int i=1;i<=n;i++){for(int j=i-1;j<=n;j++){for(int x=1;x<=m;x++){for(int y=x-1;y<=m;y++){ans=max(ans,f[i][j][x][y]);}}}}cout<<ans<<'\n';}return 0;
}//分讨(较慢) 

暴搜:

听说或许可以构造数据 \(hack\) 掉?

但目前看来的确是最优解无疑了。

我们分别枚举 \(a,b\) 串的回文中心(记得特判一下回文串长度为偶数的情况呀),然后跟上面的 \(dp\) 转移相似,分别向左右暴搜就行了。

复杂度为 \(O(能过)\)(其实是我不会算😛)

代码:

$code$
#include<iostream>
using namespace std;
int T,m,n,ans;
string a,b;
inline void dfs(int la,int ra,int lb,int rb,int len){ans=max(ans,len);if(la>=1&&ra<=n&&a[la]==a[ra]) dfs(la-1,ra+1,lb,rb,len+2);if(la>=1&&rb<=m&&a[la]==b[rb]) dfs(la-1,ra,lb,rb+1,len+2);if(lb>=1&&ra<=n&&b[lb]==a[ra]) dfs(la,ra+1,lb-1,rb,len+2);if(lb>=1&&rb<=m&&b[lb]==b[rb]) dfs(la,ra,lb-1,rb+1,len+2);}
int main(){
//	freopen("string.in","r",stdin);
//	freopen("string.out","w",stdout);ios::sync_with_stdio(false);cin>>T;while(T--){ans=0;cin>>a>>b;a=' '+a;b=' '+b;n=a.size()-1;m=b.size()-1;for(int i=1;i<=n+1;i++){for(int j=1;j<=m+1;j++){dfs(i-1,i,j-1,j,0);if(i!=n+1) dfs(i-1,i+1,j-1,j,1);if(j!=m+1) dfs(i-1,i,j-1,j+1,1);//回文长度为偶数 }}cout<<ans<<'\n';}return 0;
}//暴搜(最快) 

一组 \(hack\) 数据

T2:数排列(perm)

思路:

嘿,有个 \(O(n^3)\) 的做法没听,当时光顾着笑(一些不明事物)了。这里只提供 \(O(n^2)\) 的做法。

我们设 \(f_{i,j}\) 表示数字 \(i\) 放到 \(j\) 的位置上的合法方案数,然后再前/后缀和优化一下撒~~

对于一个数 \(i\) ,若 \(s_i=1\) ,则我们设 \(f_{i,j}\) 表示 \(i\) 放在前 \(j\) 个位置的方案数 \(dp_{i,j}=\sum_{j=1}^{i} dp_{i-1,j}\)

代码:

$code$
#include<iostream>
using namespace std;
const int N=2025,mod=1e9+7;
int n,s[N],f[N][N],ans;
int main(){freopen("perm.in","r",stdin);freopen("perm.out","w",stdout);ios::sync_with_stdio(false);cin>>n;f[0][1]=1;for(int i=1;i<n;i++) cin>>s[i];for(int i=1;i<n;i++){if(s[i]==1) for(int j=2;j<=i+1;j++) f[i][j]=(f[i][j-1]+f[i-1][j-1])%mod;else for(int j=i;j>=1;j--) f[i][j]=(f[i][j+1]+f[i-1][j])%mod;}for(int i=1;i<=n;i++) ans=(ans+f[n-1][i])%mod;cout<<ans<<'\n';return 0;
}//O(n^2)

T3:树上的背包(knapsack)

思路:

这里提供根号分治和折半搜索两种思路。

折半搜索:

代码:

$code$
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N=1e5+5;
int n,Q,x,L,cnt,tot1,tot2,ans,v[N],w[N],vl[N],wei[N];
struct flower{int val,weight;bool operator<(const flower &css)const{if(weight!=css.weight) return weight<css.weight;else return val<css.val;}
}a[N],s1[N],s2[N];
inline void dfs1(int pos,int weight,int val){if(weight>L) return ;if(pos==cnt/2+1){s1[++tot1]={val,weight};return ;}dfs1(pos+1,weight,val);dfs1(pos+1,weight+a[pos].weight,val+a[pos].val);
}
inline void dfs2(int pos,int weight,int val){if(weight>L) return ;if(pos==cnt+1){s2[++tot2]={val,weight};return ;}dfs2(pos+1,weight,val);dfs2(pos+1,weight+a[pos].weight,val+a[pos].val);
}
signed main(){freopen("knapsack.in","r",stdin);freopen("knapsack.out","w",stdout);ios::sync_with_stdio(false);cin>>n;for(int i=1;i<=n;i++) cin>>v[i]>>w[i];cin>>Q;while(Q--){tot1=tot2=ans=cnt=0;cin>>x>>L;a[++cnt]={0,0};while(x){a[++cnt]=(flower){v[x],w[x]};x/=2;}dfs1(1,0,0);dfs2(cnt/2+1,0,0);sort(s1+1,s1+tot1+1);sort(s2+1,s2+tot2+1);for(int i=1;i<=tot2;i++) s2[i].val=max(s2[i].val,s2[i-1].val);for(int i=1,j=tot2;i<=tot1;i++){while(j&&s2[j].weight+s1[i].weight>L) j--;if(s1[i].weight+s2[j].weight<=L) ans=max(ans,s1[i].val+s2[j].val);}cout<<ans<<'\n';}return 0;
}//折半搜 (慢) 
/*
3
1 2
2 3
3 4
3
1 1
2 5
3 515
123 119
129 120
132 112
126 109
118 103
115 109
102 100
130 120
105 105
132 115
104 102
107 107
127 116
121 104
121 115
8
8 234
9 244
10 226
11 227
12 240
13 237
14 206
15 227*/

根号分治:

代码:

$code$
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+5,maxn=511;
int n,x,l,Q,dp[520][N];
struct flower{int v,w;
}a[N];
inline int work(int x,int l){if(l<0) return -1e9;if(x<=maxn) return dp[x][l];return max(work(x>>1,l),work(x>>1,l-a[x].w)+a[x].v);
}
int main(){
//	freopen("knapsack.in","r",stdin);
//	freopen("knapsack.out","w",stdout);ios::sync_with_stdio(false);cin>>n;for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].w;for(int i=1;i<=min(maxn,n);i++){if(i>>1) memcpy(dp[i],dp[i>>1],sizeof(dp[i]));for(int j=N-5;j>=a[i].w;j--){dp[i][j]=max(dp[i][j],dp[i][j-a[i].w]+a[i].v);}}cin>>Q;while(Q--){cin>>x>>l;cout<<work(x,l)<<'\n';}return 0;
}

T2,T3未完...

后言:

感谢gyh提醒。

祝阿联生日快乐呀~~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Google Skills免费开放啦

Google Skills免费开放啦家人们,AI圈的大事来啦!Google搞了个大动作,直接把内部的AI学习资源打包成“Google Skills”平台,向全球开放!这波操作直接把AI学习的门槛拉到超低,普通人也能轻松上车!免费用户直接用G…

ABP - 缓存(Caching)[IDistributedCache、ICacheManager、ICacheKeyNormalizer、[Cache]、[CacheInvalidate]]

(一)缓存(Caching) 核心辅助类:IDistributedCache:分布式缓存(基于Redis等)。 ICacheManager:缓存管理器(支持多级缓存)。 [Cache]:方法缓存特性。 ICacheKeyNormalizer:缓存键标准化器,自动添加租户前缀…

好想成为人类啊——2025 . 10 . 24

好想成为人类啊。 今天应该是比较著名的程序员节,貌似大家都在庆祝。但我其实没啥感觉,因为我的理想并不是成为一个程序员。 那我的理想是什么呢,也好像并没有什么理想,可能跟艺术方面沾点儿边吧,当然,这怎么看都…

10 24(+第14场补题)

14.3维护 \(cur\), \(ans\) , \(dif = cur - ans\) 。 每次执行 \(cur = cur + a_i, \quad dif = dif + a_i\)。如果 \(cur < 0\),则 \(dif -= cur, \quad cur = 0\)。 如果 \(dif > 0\),则 \(dif = 0\)。考虑…

详细介绍:C++ 位运算 高频面试考点 力扣 268. 丢失的数字 题解 每日一题

详细介绍:C++ 位运算 高频面试考点 力扣 268. 丢失的数字 题解 每日一题pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

详细介绍:第十六届蓝桥杯软件赛C组省赛C++题解(京津冀)

详细介绍:第十六届蓝桥杯软件赛C组省赛C++题解(京津冀)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…

《打造自己的 DeepSeek》第 1 期:为什么要打造自己的 DeepSeek?

近些年 AI 大火,不过在国内真正火起来还是源于今年春节期间的 DeepSeek。 个人认为有两方面原因:一方面是 DeepSeek 使用方便。由于众所周知的原因,国内对国外网站的访问是有诸多限制的,其中就包括各大 AI 模型的官…

ret2text

from pwn import * io = remote("39.106.48.123", 29826) payload = b"A"*264 + p64(0x401202) io.sendline(payload) io.interactive() 264即258+8,258是rbp的位置,ida里一般是16位,0x401202为…

ABP - 异常处理(Exception Handling)[AbpExceptionFilter、UserFriendlyException、IExceptionSubscriber]

一、异常处理(Exception Handling) 常用核心辅助类:AbpExceptionFilter:自动捕获并处理异常。 UserFriendlyException:用户友好异常(直接返回给前端)。 IExceptionSubscriber:自定义异常订阅。1、核心类全解析…

2025年沸腾干燥机厂家权威推荐榜单:专业直销与高效节能技术深度解析,提供优质沸腾干燥设备及定制方案

2025年沸腾干燥机厂家权威推荐榜单:专业直销与高效节能技术深度解析,提供优质沸腾干燥设备及定制方案 沸腾干燥技术作为现代工业干燥领域的重要工艺,凭借其高效的传热传质效率和均匀的干燥效果,在制药、化工、食品…

CF Round 1046(#2135) 总结

CF Round 1046(#2135) 总结 A 可以 DP,用 vector 存下这个数出现的位置。 B 考虑移动到无限远处,如果移到左下角,容易发现离的最近的点就是离 \((-10^9,-10^9)\) 最近的点。这样就能确定一条直线(确定 \(x+y\))。…

重组蛋白表达的几种类型介绍

一、引言 重组蛋白表达(Recombinant Protein Expression) 是分子生物学与蛋白质工程中的核心技术。通过将目标基因导入特定宿主系统,可以在细胞内合成外源蛋白。不同的表达类型反映了蛋白在细胞中的定位方式、折叠状…

Luogu P5479 [BJOI2015] 隐身术 题解 [ 紫 ] [ 多维 DP ] [ 交换维度 ] [ 后缀数组 ] [ 哈希 ]

隐身术:挺巧妙的一道题。 首先考虑一个暴力:将“子串”的条件转化为对每一个后缀的前缀考虑,枚举每一个后缀。然后对每一个后缀做一个编辑距离的 DP,统计答案即可。 具体地,编辑距离的 DP 状态定义为:\(dp_{i, j…

2025年10月23日

A. 萌萌甜酱 洛谷原题:https://www.luogu.com.cn/problem/P3621题目 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西。 你准备给 Ike 买一个风铃。风铃是一种多…

大象《Thinking in Projects》读书笔记2

大象《Thinking in Projects》第二部分聚焦项目执行阶段的核心逻辑与实践方法,与第一部分强调的项目思维搭建形成紧密衔接,为大三学生从理论学习转向实践落地提供了关键指引。​ 这部分内容首先深入剖析了项目进度管…

06_DNS解析:从域名到IP地址

本文将通过C语言,手写实现一个基于UDP编程的DNS域名解析。一.DNS是什么? DNS(Domain Name System)的作用将我们容易记忆的域名转换为计算机可以处理的IP地址,DNS 使用 TCP 和 UDP 端口 53。 常用的nslookup命令,可…

ABP - 接口授权 [Authorize、AllowAnonymous、IPermissionChecker]

接口授权(Authorization) 核心辅助类:[Authorize]:标记需要授权的接口。 [AllowAnonymous]:允许匿名访问。 IPermissionChecker:手动检查权限。接口授权(Authorization)核心类示例与讲解 接口授权是在“身份认…

日总结 17

对比维度 BS 架构(Browser/Server,浏览器 / 服务器) CS 架构(Client/Server,客户端 / 服务器) 部署方式 仅需部署服务器,用户通过浏览器(如 Chrome、Edge)访问,无需安装客户端。 需同时部署服务器和客户端,…

杂题选做-3

杂题选做-3 #21 P9755 题目传送门 首先,看上去这个题直接不是很友好,我们考虑二分转为判断性问题。 然后一个这类在树上 topo 遍历每一个节点的最优方案类问题有一个 Trick:我们找出当前最优的节点,将其与其父亲合…

10.24每日总结

今天主要的课程有人机交互和机器学习,软考网课已经学到第六章了,前两天没有上传笔记,一会儿把这两三天的都传到这篇,距离考试还有半个多月,加油!