文章目录
目录
那可真蠢!—题记
求最长不下降子序列时把自己重复计算
用O(n^2)做法求最长上升没事,一到不下降就发现ans始终比正确答案多一倍
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
if(a[i]>=a[j])
f[i]=max(f[j]+1,f[i]);
ans=max(ans,f[i]);
}
百思不得其解,结果被老师教做人了…
原来我的i从1开始且j会取到i
导致我的每个数的更新都起到了相当于f[i]=max(f[j]+2,f[i])
的效果…
亏我还以为我的最长上升子序列写的是对的呢…
原来只是无法取到自己从而造成贡献而已…
正确写法如下
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
if(a[i]>=a[j])
f[i]=max(f[j]+1,f[i]);
ans=max(ans,f[i]);
}
求区间大于等于k的值之和时没有维护小于k的值
结果就是一旦区间中有一个点权小于k,后面的和就全成0了,因为这个点根本没被更新
想想都觉得蠢,直接发正确代码了
for(int i=1;i<=n;i++)
{
if(w[i]>=ans)
{
prs[i]=prs[i-1]+v[i];
prs2[i]=prs2[i-1]++;
}
else
{
prs[i]=prs[i-1];
prs2[i]=prs2[i-1];
}
}
Floyd求最短路条数时重复计算
害得我查了两节课错的神之二连:
1、将dis[i][j]更新成dis[i][k]+dis[k][j]同时更新最短路条数
2、if(dis[i][j]==dis[i][k]+dis[k][j]) 再更新一遍
如下
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
num[i][j]=num[i][k]*num[k][j];
}
if(dis[i][j]=dis[i][k]+dis[k][j])
num[i][j]+=num[i][k]*num[k][j];
}
改法一:后判断大于的情况
改法二:先判断大于,加个continue
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
num[i][j]=num[i][k]*num[k][j];
continue;
//像这样
}
if(dis[i][j]=dis[i][k]+dis[k][j])
num[i][j]+=num[i][k]*num[k][j];
}
把被减数取模
结果搞出了负数
把被除数搞成0
一开始定义了一个int数组,用memset初始化
后来改成double然而自己并不知道double是无法被memset填充的
因此数组里全是0,一被除就搞出了inf
(就是这个玩意)
没有用文件输入编译带if(scanf()!=EOF)的代码
结果无法输入,还以为我电脑坏了
初始化与不与起点连通的点的判断不统一
比如说把dis初始化为-1,然后用if(!dis[])判断
这要能过就见鬼了
枚举点及其能访问到的点时写错变量
比如for(int j=head[i];j!=-1;j=e[i].next)这种
把起点和起点所在的强联通分量搞混
切记!tarjan缩完点后一定要以原起点所在的强连通分量为新起点
正确示范:
std::queue<int>q;
int start = color[1];
dis[start]=sum[start];
q.push(start);
把二维数组压成一维然后并没有开大空间
于是疯狂re,还以为是转移的时候边界判错了,调了1h
两重循环又特喵的重了名
佛了
虽然改完还是挂了
当有点的标号是0时,head一定要初始化为-1!!!
坑