您的位置:首页 > 其它

151102的测试总结

2015-11-02 16:38 218 查看

第一题

【题目及题号】ball superoj990

【题解】

本题就是要求一串连续的数的乘积,并且比较大小。

如果写高精度是明显会超时的。

因为题目保证两个人的差值至少超过较小的那个的1%,所以我们可以把乘法问题转换成加法。

对每个数x求一个log(x),然后加起来比较大小。

【注意】

对于log(0)要记录一个答案最终为0的标记。

对于负数要统计个数,然后log(0-x)计算。

大数据可以转log算,然后就不用写高精了开心。

第二题

【题目及题号】array superoj991

【题解】

20%~40%

f[i][j]表示上面那行删到数i,下面那行删到数j的最小代价,然后可以n^4转移。

100%

考虑性质,sum[i]-klen实际就相当于把每个数-1,来抵消掉它的长度。

代价就变成了sum(ai~aj)*sum(bl~bg)

现在发现一个很有趣的性质,(a+c)*(b+d) > ab+cd;

这就相当于说我们可以一个一个元素考虑。

如果考虑将上面的元素并入前面删掉的集合,那么就由f[i+1][j]转移而来;

如果考虑将下面的元素并入前面删掉的集合,那么就由f[i][j+1]转移而来;

如果考虑重新分成一份,就由f[i+1][j+1]转移而来。

f[i][j] = min(f[i+1][j],f[i][j+1],f[i+1][j+1])+a[i]*b[j];

【注意】

本题数据可能会爆Int 然而long long[5000][5000]是肯定会炸内存的。

所以使用滚动数组。(注意一下,滚动数组有时候不需要赋初值,然而本题必须赋初值)

另外 我自己写的时候没有注意好边界wa了一发。

滚动数组部分代码见下

memset(f,63,sizeof(f));
f[0][m+1] = 0;
for(int i=n;i>=1;i--){
now^=1,last^=1;
for(int j=0;j<=m+1;j++)f[now][j] = INF;
for(int j=m;j>=1;j--){
f[now][j] = min(f[last][j],min(f[now][j+1],f[last][j+1]))+a[i]*b[j];
}
}
cout<<f[now][1]<<endl;


第三题

【题目及题号】date superoj992

【题解】

本题求路径中有割边的点对数量。

正向去做是可以做的,就是情况太多,很麻烦。

所以我考虑逆向来做,就相当于求不止一条路径的点对数量x,allnum-x即可。

再往下想一步,什么样的点对直接会不存在割边?自然他们在同一个环中。

问题自然转化成了求一个环。

最后可以使用tarjan,因为是无向图,我保证使用过的边不再被反向使用一遍即可。

size从2开始计数,然后当前边^1即为反向边的编号,特判即可。

【注意】

allnum=n∗(n−1)2;allnum = {n*(n-1)\over2};

x=∑itotnum[i]∗(num[i]−1)2x = \sum^{tot}_i {{num[i]*(num[i]-1)}\over2}

tot为双连通分量的数量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: