您的位置:首页 > 其它

近期总结_xdu 10月赛

2011-12-07 23:00 211 查看

XDU_OJ


10月赛

purpleplace

思路比较简单,从0~99999枚举就可以,但是要注意到每一位的数字表示的是状态,是可以出现前导0的。

所以输入时要用%s读取数据,枚举的数字转成string时注意些细节......

魔法喵点喵

 题目比较啰嗦,描述的是dp问题,造个3维数组dp[k][i][j],来表示第1个位置放k,第i个位置放j的最大值,同时预处理好每种j,前面能放的pre[j][]和后面能放的next[j][]就行了

转移方程:dp[k][i][j]=max{dp[k][i-1][t]+w[i][t])};其中t是pre[j][]中的元素;由于要满足环状结构,最后一个位置根据倒数第2个和第1个特殊判断

彩云国的经济建设

 题意比较难懂,仔细理清楚,其实是个普通的统计问题,选择恰当的数据结构就能轻松解决,输入数据中岛的名字是string,注意处理好。

细胞分裂

 最小生成树模型,不知道为神马月赛的时候不停地wa,月赛完一提交就过了--......,要注意的地方就是,并查集里最后合并节点x,y时,要合并它们的父亲fa[x]=fa[y];

弱弱的军事演习

 输入数据很多,充分体现了模块化的重要性。在这里首次意识到到排序算法选择的技巧,普通情况用自带的qsort函数就行了,而这里情况比较特殊,需要多次求前k项的和,而且元素数量很大,所以要用到另一种快速排序。

伪代码:

拓展欧几里得

1intx,y;
2extculid(inta,intb)
3{
4inttmp;
5if(b==0){x=1,y=0;return}
6extculid(b,a%b);
7tmp=x;
8x=y;
9y=tmp-a/b*y;
10}


证明:

ax+by=gcd(a,b);其中a>b;

b*x'+a%b*y'=gcd(b,a%b);

gcd(a,b)=gcd(b,a%b)    (这就是‘拓展欧几里得’名字的来历)

将a%b=a-a/b*b;代入

x=y';

y=x'-a/b*y'

递归边界是特殊解b=0时gcd(a,b)=a;->x=1,y=0;


Let'sSPFA3

 无向图求最小圈。要是直接在邻接矩阵里查看对角线的值,必定wa死,因为无向图中1条边就是一个圈了--'

 正确的办法应该是设ukv为最小圈中的3个点k为u->v最短路径上标号最大的点则路径应该为dist[u->v](不经过k点的最短路)+dist[v->k->u](经过k点的最短路)

怎样求不经过k点的最短路呢?

 floyd算法里,迭代n次,每次相当于在u,v之间试图加入i节点,那么只要i在k之前,k就不会被加入u,v的最短路径,可以用一个3维数组来存每次迭代的结果

 d[k][i][j]为第k次迭代时i,j的最短距离

 那么答案即为d[0][i][k]+d[0][k][j]+d[k-1][i][j]的最小值(k<n&&k!=i&&k!=j&&i!=j)

 到这里可能还存在问题,i,j的最短路径中只考虑了标号为k-1之前的节点,这个答案是否太片面呢?

 将圈中的节点,按标号从小到大排序v1,v2.....i,j,k长度为d[k-1][v1][j]+d[0][j][k]+d[0][k][v1];

 因为枚举了k,i,j,所以上述情况不会被遗漏,同一个最小圈会有很多表示方式,只要枚举到了一个就行了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: