今日所学:枚举与模拟
**
**
所得主要感悟:
&1:程序大小与时间控制
例: 最大连续和
给定N个数,求这N(1 <=N <= 100,000) 个数的某个连续子序列的累加和,保证这个连续子序列的累加和最大。
<1> 三重循环
枚举起点
枚举终点
求累加和
for (int i=1;i<=n;i++)
for (int j=i;j<=n;j++)
{
int sum=0;
for (int k=i;k<=j;k++)
sum+=a[k];
if (sum>ans) ans=sum;
}
这种方法利用三重循环,当n>500时基本要超时…
<2>前缀和预处理
类似于大数据版的数组求和中的处理方式
int main()
{
int maxx=-10000000;
for(int i=1;i<=n;i++)
{
sum[i]+=sum[i-1]+a[i];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int t=sum[i]-sum[j-1];
if(t>ans) ans=t;
}
return 0;
}
还是太麻烦,不稳妥
<3>如果当前累加和为负数,无作用
反之,会让后边累加和变大
int sum=0;
ans=-100000000;
for (int i=1;i<=n;i++)
{
sum+=a[i];
if (sum>ans) ans=sum;
if (sum<0) sum=0;
}
简单易懂
&2:预处理
例如火柴棒问题中的火柴棒个数进行系统化的开数组
for (int i=10;i<=2222;i++)
stick[i]=stick[i/10]+stick[i%10];
这里火柴棒若一一枚举就过于麻烦,故将一个数字分为两部分,分别求个数,再相加即为本数字的火柴棒个数
&3:bool 形式的灵活应用
通过bool类型的“真假”特性,有时可以很方便的简化问题
例如当我们多次判断一个代码的返回值时,巧用bool的两种情况,可以很方便的简化代码
例:题目:牛式
下面是一个乘法算式,但是所有的数字都看不见了。
**如果一个 星号 可以是任何一个数字,想必这个虫食算有相当多的解;
但如果一个星号只能从给定集合中选取数字,那么这个虫食算有多少个解呢 **
这里需要简单的判断乘法情况,则需重点考虑进位情况和是否在给定的集合中
故而巧妙运用bool
int num[10]
bool flag[10]
for(int i=1;i<=n;i++)
{
cin>>num[i];
flag[num[i]]=1;
}
这里的1表示在集合中
后面进位的表示是否成立可以用到
if(a[i]+a[i+1]>=10)
{
a[i+1]++;
a[i]-=10;
flag=1;
}