目录
保持微笑:这次的总结很厚
三小时三道题
不幸的,只因在人群中看了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; }