
题解
Fighter_sky
小蒟蒻啦~
展开
-
USST新生训练赛3KLMN
KLMN是数据结构(线段树/树状数组)+dp+数论+结论唐题。原创 2024-06-04 08:59:56 · 1358 阅读 · 0 评论 -
USST新生训练赛div2+div3题解
USST新生训练赛题解原创 2024-05-28 18:45:27 · 983 阅读 · 4 评论 -
ybtoj火车载客(精)
ybtoj火车载客问题(精)这题很有意思,花了我5h,最终在一众大佬围攻下,终于出来了文章目录ybtoj火车载客问题(精)题意起始の思路题意大概意思就是限客c人的列车经过n站,现在有k个站,每个站有一组人,他们起点相同终点相同,现在我们要在不超载客量的情况下让能到达的人数最大(可以不整组取),求人数是多少起始の思路对于每组人,起点和终点组成的线段可以拆分为起点和终点(废话),这样对于所有点不管起点还是终点,我们可以将其离线,并且按照时间进行排序,枚举到每站的时候列车会发生什么那么列车上会发原创 2021-09-06 22:52:21 · 493 阅读 · 2 评论 -
莫队练习之离散化:P3709 大爷的字符串题
文章目录一点吐槽题意思路代码出现的问题一点吐槽此题收录于《语文阅读理解竞赛题》出题人语文绝对有问题题意其实很简单给定一个序列,m个询问包括l、r,求l到r区间内众数的出现次数思路对于此题我们不但要维护每个数出现的次数,而且要处理当某一个数不再是众数的时候,如何更新考虑记录众数序列的记录,但是很难进行更新考虑不记录具体数字,只根据次数判断是否是众数记录每个数字出现的次数,判断相同出现次数是否有其他数字,有则不需要更新,没有则需要更新出现的次数为了避免出现相同的数据,对数据进行离散化.原创 2021-07-02 12:47:44 · 116 阅读 · 0 评论 -
莫队练习之基础练习:P2709小B的询问
文章目录题意思路代码题意给定一数列,给定多个询问,询问中给定l、r,求l到r中每个数出现次数的平方的和思路询问之间不互相影响,考虑离线,考虑莫队,维护每个数出现的次数cnt[i],根据完全平方展开,可以得到更新后sum=sum+2*cnt[i]+1,离线时间复杂度O(n√n),查询O(1)代码#include<bits/stdc++.h>#define N 50005#define ll long longusing namespace std;inline ll read(原创 2021-07-01 13:02:14 · 109 阅读 · 0 评论 -
LCS及机器分配(luoguP2066)
LCS:题解:对于两个序列,枚举i为第一个序列第i个元素,j为第二个序列第j个元素每枚举到两个元素时,这两个元素有两种情况:1.一样这时我们只需要从i-1,j-1转移即可方程:dp[i][j]=dp[i-1][j-1];2.不一样这时我们需要考虑这是从上面转移来的还是下面转移来的方程:dp[i][j]=max(dp[i-1][j],dp[i][j-1]);代码:#include<bits/stdc++.h>using namespace std;int n,dp[100原创 2021-04-29 20:41:40 · 96 阅读 · 0 评论 -
合唱队形
这道题呢,思路还是很简单的显然对于整个队列我们可以枚举中间点然后呢,正反预处理最长上升子序列,就完事了代码:#include<bits/stdc++.h>using namespace std;long long n,dp1[10005],dp2[10005],maxn,t[10005],cnt,q2[10005],q1[10005];int find1(int x){ int l=1,r=cnt; while(l<r){ int mid=(l+r)>>1原创 2021-04-27 19:51:55 · 155 阅读 · 0 评论 -
拓扑排序
1.挖地雷这道题,第一想法Floyd但是一个很大的问题是怎么存路径这是一个很玄学的问题于是我就想到了很阴间的思路:hash然后一个小时之后弃然后仔细看看题面显然这是一个DAG,那么针对DAG,代码:#include<bits/stdc++.h>#define N 20005using namespace std;struct edge{ int to,nxt,cost;}e[N];int head[N],ecnt=-1,a[N],n,dis[N],in[N]原创 2021-04-22 19:32:06 · 102 阅读 · 0 评论 -
最长不下降子序列(记录路径)
对于两个序列,求两个序列的最长不下降子序列并输出路径首先,我想到的是简单的直接求,开b数组存序列,对于每个元素,如果它大于队尾元素,显然可以直接加,如果不是,那么在序列中找到第一个大于它的数并更新之,如此求即可但是一个重要的问题没办法存存出来的b并不是正确顺序而是打乱顺序所以这道题要另想方法其实很简单把原数组排个序,求下最长公共子序列就行啦代码:#include<bits/stdc++.h>using namespace std;int s1[1100],s2[1100]原创 2021-04-17 17:47:25 · 234 阅读 · 0 评论 -
解决乾隆老子的老子遇到的问题
题解:本题上手就是精密的数学推导+理性分析,过程如下:设经过a天那么(x+am-(y+an))%L=0(x-y+am-an)%L=0((x-y)+a*(m-n))%L=0(x-y)+a*(m-n)=bl;a*(m-n)-bl=(x-y)所以,就可以用同余方程,exgcd求解,具体有待补充代码:#include<bits/stdc++.h>#define ll long longusing namespace std;ll x,y,m,n,l;ll xx,yy;l原创 2021-03-23 21:01:33 · 138 阅读 · 0 评论 -
P1006传纸条
题解:本题(昆虫般的窸窣声)既然要求一个最大值,并且因为是路径式,我们不能使用贪心通过此题,考虑dp;显然,这是个矩阵dp,那么回忆下矩阵dp通式:dp[i][j]=max(dp[i][k])+决策对于此题,我们可以自然的想到正反同时走,而n的范围并不大(n<=50),考虑高复杂度(n4),得出最终状态转移方程:dp[i][j][p][q]=max(dp[i-1][j][p-1][q],max(dp[i-1][j][p][q-1],max(dp[i][j-1][p-1][q],dp[i][原创 2021-03-20 17:05:35 · 163 阅读 · 0 评论 -
最长上升子序列(LCS)题解
LCS题解:对于每个字符有两种情况,等,或不等,而对于不等我们又有两种选择,用1号序列,或用2号序列,对每次操作得到的数据取最大值即可代码:#include<bits/stdc++.h>using namespace std;int n,m,dp[1005][1005],res;char a[1005],b[1005];int main(){ scanf("%s",a); scanf("%s",b); n=strlen(a); m=strlen(b); for(int原创 2020-12-16 19:20:34 · 162 阅读 · 0 评论 -
硬币题解
硬币题解:这是一道有限背包,基本思路与完全背包一致,不同的是,每种物品有固定的选择次数,那么我们限制选择的次数即可,标记可凑成的钱数为一代码:#include<bits/stdc++.h>using namespace std;int n,m,cnt[100005],dp[100005],res;struct node{ int price,num;}coin[105];int main(){ scanf("%d%d",&n,&m); for(int i=原创 2020-12-16 19:16:25 · 1235 阅读 · 0 评论 -
采药题解
采药(曾经的第一道dpQAQ)题解:首先这是一道动态规划,动态规划是什么呢,总之这是一种综合多种决策求全局最优解的算法。动态规划的原理类似于分治,将待求解问题分为多个子问题求解,但与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。那么我们结合题目来看看,每棵药都有价值和时间两种属性,我们要在规定时间内采到最有价值的药,那么可以开一个f数组,表示当剩left时间时可以采到的最大价值,那么我们就可以得到本题的状态转移方程:dp[left]=max(dp[left],dp[原创 2020-12-16 19:12:09 · 728 阅读 · 2 评论 -
冰封王座题解
冰封王座题解:显然, 这是一道完全背包,因为每件物品我们可以取无数次,而完全背包的精髓就在于如何取无限次下面是老套话了你会发现这个核心代码与 01 背包问题的核心代码只有 v 的循环次序不同而已。为什么这样一改就行呢?首先想想为什么 01 背包问题中要按照 v=V…0 的逆序来循环。这是因为保证第 i 次循环中的状态 f[i][v]是由 f[i-1][v-w[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第 i 件物品”这件策略时,依据的是一个绝无已经选入第 i 件物品的原创 2020-12-16 19:00:27 · 242 阅读 · 0 评论 -
装箱问题题解
装箱问题题解:背包dp转移方程:f[j]=max(f[j],f[j-c[i]]+c[i])代码:#include<bits/stdc++.h>using namespace std;int n,v,dp[35],c[35],res;int main(){ scanf("%d%d",&v,&n); for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=1;i<=n;i++) for(int原创 2020-12-15 21:00:05 · 422 阅读 · 0 评论 -
tobo游戏求解
tobo游戏题解:显然,有八种转换方式,而每种组合可以转换一个序列号,BFS即可代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;int t,x,C[9]= {0,1,2,6,24,120,720,5040,40320};ll num;ll v;struct node { ll a; int s;} p[400005], now,ad;ll find(ll v) { int ss[1原创 2020-12-12 17:58:46 · 701 阅读 · 0 评论 -
救援求解
救援题解:BFS/DFS板题(虽然我倾向于DFS,但还是写了BFS)代码:#include<bits/stdc++.h>#define SIZE 1000using namespace std;queue<int> q_x, q_y, q_pos;int step[4][2] = { {1,0},{0,1},{-1,0},{0,-1}};int m,n,board[SIZE][SIZE],sx,sy,fx,fy;bool vis[SIZE][SIZE];原创 2020-12-12 17:53:09 · 183 阅读 · 0 评论 -
拔河比赛求解
拔河比赛求解题解:显然我们可以DFS一边,取出最优的情况,因为每一个人有两种状态即选和不选,所以分别进行搜索代码:#include<bits/stdc++.h>using namespace std;int t,n,a[10005],sum,ans;void dfs(int num_a,int num_c,int num_w){ if(n/2==num_c){ ans=min(ans,abs(num_w*2-sum)); return; } if(num_a>n原创 2020-12-12 17:45:10 · 1087 阅读 · 0 评论 -
自然数拆分问题求解
自然数拆分问题题解:DFS所有可能,传递当前搜索的数值,累加和以及已经取的数量代码:#include<bits/stdc++.h>using namespace std;int n,a[1005];void dfs(int x,int y,int z){ if(y>n) return; if(y==n){ for(int i=1; i<z; i++){ if(i>1) printf("+"); printf("%d",a[i]); }pri原创 2020-12-12 17:42:33 · 322 阅读 · 0 评论 -
组合数输出题解
组合数输出:题解:因为组合不需要担心顺序的问题所以从大到小挨个搜索就行代码:#include<bits/stdc++.h>using namespace std;int n,m,ans[22];void dfs(int a,int b){ if(b>m){ for(int i=1;i<b;i++){ printf("%d",ans[i]); } printf("\n"); return; } for(int i=a;i<=n;i++){原创 2020-12-12 17:39:34 · 267 阅读 · 0 评论 -
优先队列强化:非负和
非负和:题解:双写输入的数组,维护这个优先队列,使它的前缀和始终小于sum[i],则res++代码:#include<bits/stdc++.h>using namespace std;const int M=1000050;int n,a[M*2],sum[M*2];int idqu[M*2],sumqu[M*2];int main(){ while( scanf("%d",&n) != EOF) { for(int i=1; i<=n; i++) s原创 2020-12-03 21:00:17 · 197 阅读 · 0 评论 -
优先队列引入:区间最值
区间最值:题解:本题需要维护一个优先队列,队首小于当前元素就把之前的全pop,并压入,同时pop掉超时的元素,这样就可以保证队首永远是最大最新的代码:#include<bits/stdc++.h>using namespace std;int n,w;struct node{ int time,num;}a[1000001];queue<node> q;int main(){ scanf("%d%d",&n,&w); for(int i=1;原创 2020-12-03 20:54:21 · 223 阅读 · 0 评论 -
队列引入:队列练习
队列练习:题解:队列的基本操作,开队列没啥可讲的代码:#include<bits/stdc++.h>using namespace std;int n;queue<int> q;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int ope; scanf("%d",&ope); if(ope==1){ int ope1; scanf("%d",&ope1);原创 2020-12-03 20:45:48 · 133 阅读 · 0 评论 -
栈强化:车厢调度
车厢调度:题解:继续手写栈 ,只要一个数出栈,那么比这个数更小的数一定已出栈,若出现矛盾,则输出0代码:#include<bits/stdc++.h>using namespace std;int n,a[1001],ifin[1001];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++){ for(int j=a原创 2020-12-03 20:42:10 · 192 阅读 · 0 评论 -
栈引入:括号匹配
括号匹配:题解:这道题是一道栈的引入,但其实不用栈,我们只需要用数组模拟一个栈就完了,遇到一个左系列的就存入,遇到右系列就判断是否与栈顶相匹配,最后若栈为空,则TRUE,否则FALSE代码:#include<bits/stdc++.h>using namespace std;int n;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ char x[200001],a[200001]; int cnt1=原创 2020-12-03 20:36:09 · 111 阅读 · 0 评论 -
P1506 拯救oibh总部(一道我永远也过不了的题)
P1506 拯救oibh总部(一道我永远也过不了的题)题解:(gg染色法 )在矩阵外加一圈0,再DFS其实,挺水的,但是,这不是一道一般的题,我下载了第一个点的数据,本地过了,但是,我竟然爆零了,求各路大佬帮看下代码:#include<bits/stdc++.h>using namespace std;int n,m,a[1005][1005],ans;void dfs(int sx,int sy){ if(sx<=0)return; if(sy<=0)retur原创 2020-11-29 15:51:37 · 185 阅读 · 0 评论 -
零件分组 解
零件分组:一句话题解:原创 2020-11-25 18:09:43 · 552 阅读 · 0 评论 -
美元汇率 解
美元汇率:一句话题解:当买入卖出能赚$$$$时,就进行一次买入卖出代码:#include<bits/stdc++.h>using namespace std;int n,a[101];double res=100;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<n;i++){ if(a[i]>a[i+1])原创 2020-11-25 14:07:42 · 275 阅读 · 0 评论 -
P1242新汉诺塔
题解:本题显然我们要按照从大到小的顺序使圆盘归位,那么,我们每次使大盘子归位的时候,显然,其上面的小盘子需要GET OUT OF THE WAY那么我们接下来要做的就是如何让它们移开。显然,这里就和汉诺塔一致了,但我们需要一个中转,如何确定中转,就是除了from和to之外的内根柱子,即6-from-to,那么这个问题就解决了代码:/*#include<bits/stdc++.h>using namespace std;int n,from[10005],to[10005],res,x原创 2021-01-20 16:27:45 · 451 阅读 · 1 评论 -
集合的划分
这题我给两个巨神讲,结果没讲明白QAQ题解:本题看上去很复杂,实际看完解释后,就明白了还挺简单的本题细细解释就是将n个球放到k个无标号的盒子里,必须把每个盒子都放东西,但是每个盒子放几个没有限制。那么这样,对于每个球我们就有了两种选择:1.单独放到一个单独的盒子中,这样方案数并不改变,即dp[n][k]=dp[n-1][k-1]2.将球放入已有其他球的盒子,这样在每种基础上又多了i*这些种,即dp[n][k]=k*dp[n-1][k]这样我们对方案数进行整合,即可得到状态转移方程,即d原创 2021-01-20 16:16:53 · 194 阅读 · 0 评论 -
运输
题解:乍一看去,我去,这什么玩意,题都读不懂 但仔细看看,这不就反过来合并果子嘛,因为我们要/k,所以从大到小排列,这里就要引入priority_queue以降低复杂度代码:#include<bits/stdc++.h>using namespace std;int n,x,ans,k;priority_queue<int,vector<int>,less<int> >q;int main() { scanf("%d%d",&n,&am原创 2021-01-20 07:45:19 · 244 阅读 · 0 评论 -
线段覆盖PLUS
题解:将重合部分标记,最后计算有多少重合区间代码:#include<bits/stdc++.h>using namespace std;struct node{ int st,ed;}point[10005],a[10005];int n,ans;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&point[i].st,&point[i].ed); int原创 2021-01-19 14:23:56 · 142 阅读 · 0 评论 -
P1020导弹拦截
题解:首先找最长不上升子序列,即最多可拦截导弹数,这里既可以采用枚举的方式也可以采用二分的方式~~(都能过的原因可能是数据太水)~~代码:#include<bits/stdc++.h>using namespace std;int a[140000],n=1,dp[140000],x[140000];int search(int st,int ed,int p){ if(st==ed) return st; int mid=(st+ed)/2; if(x[mid]==p) re原创 2021-01-18 21:04:06 · 278 阅读 · 3 评论 -
满背包问题
题解:大法师万岁!!!!!!!!!直接dfs每一个物件即可注意什么时候return!代码:#include<bits/stdc++.h>using namespace std;struct node { int id,wei,judge;} a[100005],ans[100005];int n,s,flag;void dfs(int tot,int c) { if(flag) return; if(tot>s||c>n+1) return; if(tot原创 2021-01-18 16:34:36 · 204 阅读 · 0 评论 -
极值问题
题目:题解:咋一看好像很麻烦的, 开动机智的小脑袋瓜就可以想出来啦hhhh咳咳 其实是对条件中的公式进行变形(n2-nm-m2)2=1( m2+nm-n2 )2 =1( m2+nm-n2 )= m2+2nm+n2-mn-2n2;( m2+nm-n2 )=(m+n)2-mn-2n2;综上 可推出(n2 -n*m-m2)2=((m+n)2-(m+n)*n-n2)2即 m->n,n->m+n;嘿嘿嘿 这个时候 我们从最简单的情况带入;带入m=1时,解出n=1;带入m=2时,原创 2021-01-18 13:15:04 · 473 阅读 · 0 评论 -
士兵站队问题
题解:首先已知纵向移动可以直接通过求中位数得到那么问题就是横方向移动了我们假设第一位士兵站的位置是k,因为x从x1开始,那么我们假设成起始位置为k+1吧(不懂接着看完你就懂了)那么:第二位士兵的位置是 k+2,接着是k+3,k+4,……,k+n;所以,士兵横向(即平行于y轴方向)移动的距离为:|x1-(k+1)|+|x2-(k+2)|+|x3-(k+3)|+……+|x(n-1)-(k+n-1)|+|xn-(k+n)|那么k取何值会使上式最小?我们不妨变形一下:|(x1-1)-k)|+|(原创 2021-01-16 13:51:49 · 1499 阅读 · 1 评论 -
输油管道
题解:排序求中位数WA因:没有考虑油田个数可能有奇数和偶数两种情况原创 2021-01-16 13:27:03 · 160 阅读 · 0 评论 -
第k小整数
题解:首先进行桶排序,再依次进行枚举即可WA因:没读题,一定要 NO RESULT!!!!!!!!!!!原创 2021-01-16 13:05:48 · 480 阅读 · 0 评论 -
传纸条
传纸条题解:显然这道题给了我们矩阵和坐标,那么我们就要根据矩阵和坐标进行dp,第一感觉肯定是用dp[x1][y1][x2][y2]表示当走到(x1,y1)和(x2,y2)时最大的值,但显然这是个n4的算法,非常危险,所以我们要优化。根据题意可以知道,x+y应该就等于step+1,那么我们当已知x时,就可以得出y,那么现在我们就可以用dp[i][x1][x2]来表示当走i步,走到了(x1,y1)和(x2,y2)时的最大值,但问题又来了,就是显然每个人我们只能传一次,那么我们就进行特殊判断,当x1=x2时,原创 2020-12-21 22:34:41 · 178 阅读 · 0 评论