2011年11月2日
摘要: UVA_10405 求最长公共子序列,为了防止字符串里有空格的情况,还是直接用gets读字符串更稳妥些。#include<stdio.h>#include<string.h>#define MAXD 1010char a[MAXD], b[MAXD];int f[MAXD][MAXD];int init(){ if(gets(&a[1]) == NULL) return 0; gets(&b[1]); return 1;}void solve(){ int i, j, k1, k2; k1 = strlen(&a[1]); k2 = strle. 阅读全文
posted @ 2011-11-02 23:57 Staginner 阅读(268) 评论(0) 推荐(0) 编辑
摘要: UVA_103 首先我们应该对坐标内部排序,之后一个直观的想法就是扫描一遍所有盒子,如果i可以放到j内,就连一条i->j的有向边,然后求dfs树形图的最深层数即可。 另外,我们也可以对盒子按第一个坐标进行排序,然后去求最长上升子序列。#include<stdio.h>#include<string.h>#include<stdlib.h>int N, K, G[40][40], a[40][20], indgr[40], outdgr[40], path[40], max;int cmp(const void *_p, const void *_q){ 阅读全文
posted @ 2011-11-02 21:13 Staginner 阅读(260) 评论(0) 推荐(0) 编辑
摘要: UVA_111 这个题目并不困难,但是题意理解起来很蛋疼。 题目的意思是求两个事件序列的最长公共子序列,而题目中输入的是每个事件发生的时间,因而要先根据每个事件发生的时间把事件的序列的找到。 比如如果输入是1 3 4 2,那么实际上事件序列是1 4 2 3。#include<stdio.h>#include<string.h>#define MAXD 30int N, a[MAXD], b[MAXD], f[MAXD][MAXD];int init(){ int i, k; for(i = 1; i <= N; i ++) { if(scanf("%d& 阅读全文
posted @ 2011-11-02 20:06 Staginner 阅读(406) 评论(0) 推荐(0) 编辑
摘要: HDU_4081 这个题目大体的思路是这个样子的,首先求一个最小生成树,然后求出或者顺便求出最小生成树上任意两点间路径上的最大边权,之后枚举magic road,把magic road两个端点间的之前记录的最大边边权减去后作为B,把magic road两个端点上的人口和作为A,更新一下A/B即可。#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXD 1010#define MAXM 1000010int N, x[MAXD], y[MAX 阅读全文
posted @ 2011-11-02 02:37 Staginner 阅读(754) 评论(0) 推荐(0) 编辑
摘要: HDU_2242 这个题目首先可以求出边双连通分量并进行缩点,如果边双连通分量的个数只有一个的话就必然无解,之后我们把缩好的点建成一个新图,这个图实际上就是一棵树。 如果我们随便找个点当做树根,并把图画成树形结构的话,就会发现实际上我们只要求出除树根外每个节点以及其下方的所有节点的权值和即可,每求出一个权值和,就算一下人数差并更新一下min。同时,为了充分利用子问题的解,我们在计算结果的时候可以采用dfs的方式,每个节点返回自己以及自己下方的所有节点的权值和。 需要说明的是,由于这个题目存在两点之间有多条边的情况,于是在用tarjan时就要判断一下当前扫描的边是否是之前来到这个节点的边的... 阅读全文
posted @ 2011-11-02 02:29 Staginner 阅读(856) 评论(0) 推荐(0) 编辑