暑期集训 Day5 —— 模拟赛复盘





${\color{Green} \mathrm{Problem\ 1 :选数 }} $

签到题,一眼二分,但是打模板时死循环了:

while(L<R){
	int mid=(L+R)>>1;
	if(check(mid)) L=mid;
	else           R=mid+1;
}

后来发现 +1 要写在 check 通过的地方,不然容易 mid 值永远不变。

while(L<R){
	int mid=(L+R)>>1;
	if(check(mid)) L=mid+1;
	else           R=mid;
}

二分模板不够熟,需要多打。

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $





${\color{Green} \mathrm{Problem\ 2 :搬砖 }} $

乍一看像是01背包的变种,只要改一下内层循环的范围就行,于是便有了开始的代码:

#include <bits/stdc++.h>
using namespace std;

struct Node{
	int w;
	int c;
}A[1005];
int N,M,DP[40005],ans;

int main()
{
	scanf("%d",&N);
	for(int i=1;i<=N;i++){
		scanf("%d%d",&A[i].w,&A[i].c);
		M=max(M,A[i].c*2);
	}sort(A+1,A+1+N,[](Node a,Node b){return a.c<b.c;});
    
	for(int i=1;i<=N;i++){
		for(int j=A[i].w+A[i].c;j>=A[i].w;j--){
			DP[j]=max(DP[j],DP[j-A[i].w]+A[i].c);
		}
	}
    
	for(int i=1;i<=M;i++){
		ans=max(ans,DP[i]);
	}printf("%d",ans);
	return 0;
}

后来样例和大样例都过了,准备打 T3 ,听老师说,他到现在为止没看到一个 T2 正确的排序,于是慌慌又张张,再检查一遍,发现物品的顺序要满足 j 的最大范围递增,于是把排序规则改成了 a.w+a.c<b.w+b.c,把 j 的初值改成了 min(A[i].w+A[i].c,M),终于过了。

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $





${\color{Green} \mathrm{Problem\ 3 :语文1 }} $

下次是不是有语文2

看到题目中的这句话,立马明白是线段树。

但是区间排序怎么实现啊喂?!

赛时没想出来,打了暴力,后来才知道,需要建 26 棵线段树来维护这个字符串。线段树变化真的多。

要多打线段树题QwQ。

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $





${\color{Green} \mathrm{Problem\ 4 :旅行者 }} $

思路考场上没想出来,一直想不到可以把编号二进制分组。打了一个 36 分的暴力,吸氧 63 分。

后来知道了思路,写代码时最后一个点一直 TLE,后来用 bitset 代替 bool 才卡过。

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $

${\color{White} \mathrm{}} $





总结

期望(不开 O2):\(100+100+30+20=250\)

实际(不开 O2):\(100+100+21+36=257\)

实际( \({\color{White} \mathrm{\ \!}}\) 开 ${\color{White} \mathrm{\ !}} $ O2):\(100+100+21+63=284\)

这次比赛的分数还是比较满意的。但是时间没有规划好,导致最后一分钟才写完最后一题的暴力,大样例测完只剩几十秒了。以后要做好时间分配,正解不要想太久。

posted @ 2024-02-24 17:14  Sundar_2022  阅读(5)  评论(0编辑  收藏  举报