转眼间就已经学习acm六周了,这一周还是主要以做线性DP和打练习赛为主。
首先先来说一说在练习赛的时候,有的题你的时间复杂度太大所以导致时间超时。下面有几个简化时间复杂度的例子:
省赛训练2中的D https://vjudge.net/contest/433768#problem/D
我们需要求出一个字符数组中的给定字符串的个数。刚开始想得是用一个二重循环在上一个flag来记录这个字符数组中的字符串的个数。代码如下:
for(int i=0;i<n;i++)
{ int q=0;
if(s[i]=='x')
{ for(int j=i+1;j<n;j++)
{if(q==0&&s[j]=='t')
{q=1;s[j]='o';}
if(q==1&&s[j]=='C')
{q=2;s[j]='o';}
if(q==2&&s[j]=='p')
{ q=3;s[j]='o';}
if(q==3&&s[j]=='c')
{q=4;s[j]='o'; }
}
}
但是发现这个二重循环超过了时间。
所以就需要简化时间复杂度。
for(int i=0;i<n;i++)
{ if(s[i]=='x')
{ q++;}
else if(q&&s[i]=='t')
{q--; w++;}
else if(w&&s[i]=='C')
{w--;e++;}
else if(e&&s[i]=='p')
{e--;r++; }
else if(r&&s[i]=='c')
{t++;r--; }
}
通过使用多个flag来达到简化时间复杂度的目的。
我们还可以通过两个一重循环合并来进行代码的简化。
在这周的训练中不是很理想,有几次训练因为和大物实验还有程序设计实验冲突而导致在上实验课的时候做的所以效率和答题数量上不是很乐观。这周的题中发现要多规律和代码细节的优化。需要多积累简化代码复杂度的方法。有的题你知道思路和方法但是代码就是超时。还有就是要调整还心态,有的时候当你因为一个自己知道怎么做但是就是提交不对的题,就会刚心态。导致自己后面的题都不想看了,思绪一直在这个题中。昨天做的哪一个c题感觉思路没问题就是代码超时一直想着如何简化复杂度。但是最后看答案的时候发现这个题要使用(权值树状数组+莫队)听都没听过。所以我们在答题的时候要学会舍去。从而实现提交最大化。
整理一下关于一个数能够被几整除的规律:
可被2整除 : 偶数。
可被3整除 : 各位数字之和能被3整除。
可被4整除 : 最末两位数字所成的2位数能被4整除。
可被5整除 : 末位是 0 或 5。
可被6整除 : 同时满足被2和3整除的条件。
可被7整除 :
设一个数 abc def , 则def - abc 能被7整除 ,
又如 abc def ghi , 则ghi - def + abc 能被7整除 ,
再如 abc def ghi jkl ,则 jkl - ghi + def - abc 能被7整除, 如此类推。
以上任何字母包括首位可是0 , 此法也可以合判別能否被11或13整除。
可被8整除 : 最末三位数字所成的3位数能被8整除。
可被9整除 : 各位数字之和能被9整除。
可被10整除 : 末位是 0。
可被11整除 : 奇位数字和 - 偶位数字和能被11整除。
可被12整除 : 同时满足被3和4整除的条件。
可被13整除 : (同可被7整除之法则)
发现这个周结要从每天积累,不然到了周末自己一周出现的问题也都忘了提升也不会很大,所以以后的题解要从每天开始积累这样既然能巩固自己的疑点也是对自己的一个鞭策!
说完了训练再来说一说线性dp吧:线性dp的题虽然快结束了,但是线性dp对于我来说远远没有结束,我对线性dp的认知还是非常浅的,很多题都不仅仅找不到状态方程,就连状态我找起来都很困难,昨天提交了一个题提交了20次最后才过,那个题原本应该两边就过的但是因为我的语言选了一个clang的语言没有选那个c++的导致那个题提交一次不过提交一次不过,在这个给大家避个雷。上一次课还开了区间dp,没怎么听懂看来以后的几天的任务就是训练、线性dp巩固、背包和区间dp的学习。还有就是老师之前发的博弈还没怎么看,虽然我队伍里这不是我的任务,但是从长远上来看,博弈还是需要了解一下的。