CSP-S模拟记

目录

保持微笑:这次的总结很厚

题解

T1

T3


保持微笑:这次的总结很厚

三小时三道题

不幸的,只因在人群中看了T3一眼,上头了

草草看过T1T2,觉得T3最容易下手(??)

以至于连T1的题目都没理解

无论如何,打T3的代码,特判加起点终点加状态规划

#define ri register int	
for(ri len=1; len<n; len--)
		for(ri st=2; st+len-1<=n-1; st++) {
			ri en=st+len-1;
			for(ri k=st+1; k<en; k++)
				f[st][en]=max(f[st][en],f[st][k]+f[k+1][en]+s[k]); }

自信表示:样例没过,debug

de出来的是之前写的合并石子,两道题一起,思路炸了

+50min 浅放一下T3

+20min 读T2,练习过,默代码,过样例,结束

这时第三个槽点出现了

急着调T3,T1读成判断子串,我:开不了开不了

+70min 乱码一样的思路,T3连着改了几种算法,过不去

回看T1,终于发现读题似神游,读了个寂寞

之后:分析、分析不下去、分析、分析不下去

最后,雪崩

上头这破毛病第一次直接爆零,万万没想到还有第二次(?!)

题解

T1

简介 按规律写代码

什么判断子串,飞吧

只须注意输入换行,string2^31上下范围

#define ri register int
int T;
char ch[10000001];
int main() {
	scanf("%d\n",&T);
	for(ri j=1,i=0,flag=0; j<=T; j++,i=0,flag=0) {
		while(ch[++i]=getchar()) {
			if(ch[i]=='\n') break;
			if(ch[i]!='t'&&ch[i]!='l') flag=1;
			if(i!=1&&ch[i]=='l'&&ch[i-1]=='l') flag=1; }
		if(flag) printf("0 0\n");
		else if(ch[1]=='t') printf("0 1\n");
		else printf("1 1\n"); }
	return 0; }

T3

简介 区间dp

初见,针对01背包类似的动态规划,存在一个问题:如何实现合并后删除的操作

做减法不容易,但做加法可以,即用删除后的部分加上合并的部分

也就是区间dp

问题 输出错误 错加了s[k],和合并石子弄混了;时间 缺少ans的简化,三层for有重叠

#define ri register int
#define ll long long
int main() {
	memset(f,-0x3f3f3f3f,sizeof(f));
	scanf("%d%d",&n,&k);
	for(ri i=1; i<=n; i++) {
		scanf("%lld%lld",&a[i],&b[i]);
		if(a[i-1]+a[i]<=k&&i!=1) f[i-1][i]=b[i-1]+b[i]; }
	for(ri len=4; len<=n; len+=2)
		for(ri st=1; st+len-1<=n; st++) {
			ri en=st+len-1;
			if(a[st]+a[en]<=k) f[st][en]=max(f[st][en],f[st+1][en-1]+b[st]+b[en]);
			for(ri k=st+1; k<en-1; k+=2)
				f[st][en]=max(f[st][en],f[st][k]+f[k+1][en]); }
	for(ri i=2; i<=n; i++) {
		ans[i]=ans[i-1];
		for(ri j=i%2; j<i-1; j+=2) ans[i]=max(ans[i],ans[j]+f[j+1][i]); }
	printf("%lld",ans[n]);
	return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值