题目:http://codeforces.com/contest/229
A:细节要处理好,乱搞
B:
题意:一个有权无向图,给出每个点限制的时刻,表示不能在该点限制时刻出发到其他点,求s到t的最短路。
思路:直接跑dijkstra,点出队列的判断下该时刻是否为限制时刻,如果是,往上加直到不是即可。
C:
题意:给你一个完全图,Alice选了m条边,剩下的都是Bob的边,问Alice和Bob各自的图中三角环总共有多少个。三角环为长度为三的环。
思路:算出少掉的三角环个数,总的个数减去该个数即为答案。少掉的三角环有两种情况,一种是两个点有边,但是他们和另一个点都没有边,还有一种是两个点有边,他们只有一个点和另一个点有边。
对于一个点,要计算和他关联的少掉的三角环的数量,那首先必然有一个点和他相邻的,如果另一个点和他不相邻,那么这个三角环必然是少掉的三角环,如果另一个点和他相邻,也有可能是三角环,但是我不用把他计算在内,因为考虑这样的情况必然是会在另外两个点计算到的。所以对于每个点ans都加上这个点的相邻的点数乘以不相邻的点数,这样得到的ans/2就是答案了。
D:
题意:给你一个长度为n的数列,每次可以选择两个相邻的数合并,即两个数变成一个相加后的数,要使得最后的数列单调不下降,问至少需要几步操作。(n <= 5000)
思路:因为每次都是选择两个相邻的数进行合并,某个数和前面的合并后的不同情况不超过n种,所以就可以直接dp了。
val[i][j]表示第i个数为v[i][j]的时候最少需要几次操作。
因为第i个数往回合并到第j个的数后的数是随i的增加而递增的,所以可以加些小优化,我的pot[i]表示第i个数处理到pot[i]的位置了。
E:
题意:给你m个集合,每个集合中的数都是不同的,要你选出n个数,并且选出n个数的和是最大的,问这样的概率是多少。n,m<=1000
刚开始纠结了很多还是想不大出,后来才发现每个集合的数都是不同的。。。其实我前面考虑了好久,如果这样子的话我已经想通啦!
思路:因为选出n个数的和是最大的,所以对所有的数从大到小排序后,比第n个数大的数都是必须要选的,不过和第n个数相等的数选哪些是不确定的,设第n个数为x。所以有dp[i][j]表示处理到第i个集合已经选了j个x的概率,cnt[i][j]表示处理到第i个集合已经选了j个x的不同情况数,对于第i个集合,大小为sz的集合,设大于x的数有k个,如果没有等于x的数,直接转移dp[i][j] += dp[i-1][j]*1/( C(sz, k) ), cnt[i][j] += cnt[i-1][j],如果有等于x的数,dp[i][j+1] += dp[i-1][j]* 1/( C(sz, k) ), cnt[i][j+1] += cnt[i-1][j], dp[i][j] += dp[i-1][j]* 1/( C(sz, k-1) ), cnt[i][j] += cnt[i-1][j]。仔细想想其实挺简单的,转移也很清楚,这里我用了滚动数组。