UVA 10534 - Wavio Sequence
摘要:这道题的意思是让我们求一个上升子序列 + 一个下降字序列,且两边的长度是相等的,由于用正常的 O(n2) 算法会 TLE ,所以这里我们采用二分法求最长上升子序列,这里需要利用两个栈来储存“相当于”最长上升子序列的串(我利用一个栈通过再次初始化栈顶top来第二次使用),在此同时开两个数组f1[i],f2[i],分别表示前i个元素的最长字串长度,最后比较同一个位置时(注意f1,f2一个正一个反)两个数组值的大小,取小的一个(因为要求两边长度相等)赋值给新开的数组flag[](我用num不断刷新),最后遍历数组,找出其最大的就可以了。这里说一下二分法求最长上升子序列:复杂度为O(n×lo
阅读全文
posted @
2012-03-31 22:35
BFP
阅读(787)
推荐(1)
uva 10069 - Distinct Subsequences
摘要:终于弄出来了,不会做的都是难题,会做的都是水题啊,水啊。这道题的大意是:从母串里找出有多少个子串为给出的字串,分两步思考:一 是先把状态方程写出来,由题分析我们可以这样设状态:f[i][j] = f[i][j-1];if(b[i] == a[j]) f[i][j] += f[i-1][j-1];这里解释一下:这里的f[i][j]表示字串前 i 个组成的字串,在前 j 个母串中出现的次数,例如:母串:babgbag 状态中前 j 个字符组成的字串字串:bag 状态中前 i 个字母组成的字串为什么这样可以呢:因为前 i 个字串在前 j 个母串中出现的次数必然大于在前 j - 1个母串中出现的...
阅读全文
posted @
2012-03-29 00:59
BFP
阅读(657)
推荐(1)
UVA 825 - Walking on the Safe Side(重做)
摘要:这道题改天重新做一下:高人的代码:#include<stdio.h>#include<string.h>#include<ctype.h>#define MAXD 1010char b[10010];int N, M, G[MAXD][MAXD], f[MAXD][MAXD];void solve(){ int i, j, k; gets(b); sscanf(b, "%d%d", &N, &M); memset(G, 0, sizeof(G)); for(i = 1; i <= N; i ++) { gets(b)
阅读全文
posted @
2012-03-23 21:12
BFP
阅读(606)
推荐(0)
UVA 620 - Cellular Structure
摘要:读了几遍题,还不知道题的意思,唉,理解能力啊,看了别人的代码之后,奥,原来是这样,这里简单说一下对题目的理解,它说我们有这样一个细胞链,其中细胞只有A和B两种,给你这个细胞链让你看一下,是不是经过所给的三种状态,可以变化成现在的状态,然后输出现在处于什么状态。的确像个DPS。代码如下:#include<stdio.h>#include<string.h>#define MAXN 100100int n, stage;char c[MAXN];char t[4][20] = {"SIMPLE","FULLY-GROWN","
阅读全文
posted @
2012-03-22 21:55
BFP
阅读(415)
推荐(1)
UVA 10404 - Bachet's Game
摘要:动规的题,还是尽量转化成动规的形式,用一个数组f[i]表示当还有i个石子该Stan取的时候,Stan是否能够获胜。代码:#include<stdio.h>#include<string.h>#define MAXD 1000010#define MAXM 15int N, M, f[MAXD], r[MAXM];void init(){ int i; scanf("%d", &M); for(i = 0; i < M; i ++) scanf("%d", &r[i]);}void solve(){ int i
阅读全文
posted @
2012-03-22 12:09
BFP
阅读(276)
推荐(0)
UVA 437 - The Tower of Babylon
摘要:是一道归根于最长上升子序列的问题,权值1改为高度h,因为要求最大上升子序列,要先排序,这里按面积升序排序,使后面的面积大的block不会叠在前面面积小的block之上,便于递推,这里用qsort排序方便很多。代码如下:#include<stdio.h>#include<stdlib.h>#include<string.h>int n, x[95], y[95], h[95], f[95], r[95];int cmp(const void *_p, const void *_q){ int *p = (int *)_p; int *q = (int *)_q
阅读全文
posted @
2012-03-21 22:41
BFP
阅读(518)
推荐(0)
UVA 10285 - Longest Run on a Snowboard
摘要:这是一道动态规划的dps问题,注意深搜的过程中做到记忆化搜索。代码如下:#include<stdio.h>#include<string.h>int n, R, C, max, a[105][105], f[105][105];char name[100];int dp(int i, int j){ if(f[i][j] != 0) return f[i][j]; if(i<=R&&i>=1&&j<=C&&j>=1) { int k, p, q; if(a[i][j] > a[i-1][j])
阅读全文
posted @
2012-03-20 23:44
BFP
阅读(319)
推荐(0)
UVA 10465 - Homer Simpson
摘要:完全背包问题,背包九讲细看一下,还有一点灵活的运用:打印剩余时间那块。代码如下:#include<string.h>#include<stdio.h>#define MAXN 10010int a[3], t, f[MAXN];void solve(){ int n = 0; memset(f, 0 , sizeof(f)); f[0] = 1; for(int i = 1; i < 3; i ++) { for(int j = a[i]; j <= t; j ++) { if(f[j] < f[j - a[i]]...
阅读全文
posted @
2012-03-20 17:49
BFP
阅读(196)
推荐(0)
UVA 531 - Compromise
摘要:最长公共子序列问题,打印路径总结了两个方法,一个是递归指向,就像前面做的01背包问题如:for(int i = 1; i < n; i ++) for(int j = 0; j < n-i; j ++) for(int k = j; k < i+j; k ++) { if(k == j) { f[j][i+j] = f[j][k]+f[k+1][i+j]+A[j][0]*A[k][1]*A[i+j][1]; ...
阅读全文
posted @
2012-03-20 12:28
BFP
阅读(1214)
推荐(1)
UVA 10130 - SuperSale
摘要:这道题开始我以为是将全家人所能携带重量的总和加起来,作为新的背包的容量,但样例过不了,后仔细一读题,原来是以每人为一个背包,最后计算各背包的总和。也就是多人的01背包问题。代码如下:#include<stdio.h>#include<string.h>#define MAXN 1000+10int T, N, G, sum;int p[MAXN], w[MAXN], mw[110], f[MAXN][35];void solve(){ memset(f, 0, sizeof(f)); sum = 0; for(int k = 1; k <= G; k ++) {
阅读全文
posted @
2012-03-19 22:08
BFP
阅读(291)
推荐(0)
UVA 624 - CD
摘要:这道背包题很基础,要学习一下dp输出,。代码如下:#include<stdio.h>#include<string.h>#define MAXN 10000int tap, cdnum, num[25],f[25][MAXN],p[25][MAXN];void print(int i, int j){ if(i == 0) return; print(i - 1, p[i][j]); if(p[i][j] < j) printf("%d ", num[i]);}void solve(){ memset(p,0,sizeof(p)); m...
阅读全文
posted @
2012-03-19 00:00
BFP
阅读(249)
推荐(0)
UVA 348 - Optimal Array Multiplication Sequence
摘要:这道题的输出路径是个问题,仔细体会。代码:#include<stdio.h>#include<string.h>#define MAXN 10 + 5int A[MAXN][2], f[MAXN][MAXN],part1[MAXN][MAXN];int n;void printpath(int a, int b){ if(a == b) { printf("A%d", a + 1); return ; } printf("("); printpath(a, part1[a][b]); printf(" x ")
阅读全文
posted @
2012-03-17 21:42
BFP
阅读(290)
推荐(0)
UVA 562 - Dividing coins
摘要:考虑全面,01背包问题:代码如下:#include<string.h>#include<stdio.h>#include<stdlib.h>#define MAXN 100 + 5#define MAXN1 25000 + 100int coin[MAXN], f[MAXN][MAXN1];int n, m, sum, c;/*int cmp(const void* _p, const void* _q){ int *p = (int *)_p; int *q = (int *)_q; return *p - *q;}*/void dp(){ int i,
阅读全文
posted @
2012-03-15 22:58
BFP
阅读(293)
推荐(0)
UVA 357 - Let Me Count The Ways
摘要:水题,不解释:代码如下:#include<stdio.h>#include<string.h>#define MAXN 30000 + 100long long f[MAXN];int chang[6] = {0,1,5,10,25,50};int n;void solve(){ memset(f,0,sizeof(f)); f[0] = 1; int max = 30000; for(int i = 1; i <= 5; i ++) for(int j = chang[i]; j <= max; j ++) f[j] += f[j ...
阅读全文
posted @
2012-03-14 23:00
BFP
阅读(222)
推荐(0)
UVA 147 - Dollars
摘要:这道题要注意高精度误差,我这样做稍有一些麻烦,不如将面值放大成1, 2, 4, 10, 20, 40, 100, 200, 400, 1000, 2000再用整数计算,省去了我这个浮点误差(代码中的+0.1)的麻烦。代码如下:#include<stdio.h>#include<string.h>double n;double chang[12] = { 0,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100};long long f[6000+10];void solve(){ double amount = 300.10; memset(f,0,s
阅读全文
posted @
2012-03-14 22:39
BFP
阅读(265)
推荐(0)
UVA 10192 - Vacation
摘要:求最长公共子序列,注意到输入有空格,用gets()就可以了。代码如下:#include<stdio.h>#include<string.h>#define MAXN 100 +10char m[MAXN], f[MAXN];int r[MAXN][MAXN], n;void dp(){ int lenm = strlen(m+1); int lenf = strlen(f+1); for(int i = 1; i <= lenm; i ++) for(int j = 1; j <= lenf; j ++) { if(m[i] ...
阅读全文
posted @
2012-03-14 14:58
BFP
阅读(224)
推荐(0)
UVA 10131 - Is Bigger Smarter?
摘要:这道题开始想麻烦了,一直在思考体重相等的情况下,分成多个子序列,再分别对其IQ进行降序排列。这是太麻烦了。换个思路,体重只是IQ降序排列的一个限制,在求其最长下降子序列时只要考虑到体重相等时IQ不能相互嵌套就可以了,只是多了一个判断语句,真是会的不难,不会的真难啊,哈哈代码如下:#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXN 1000 + 10int w[MAXN],IQ[MAXN], r[MAXN], f[MAXN], road[MAXN];int n, flag, max
阅读全文
posted @
2012-03-14 00:12
BFP
阅读(598)
推荐(0)
UVA 116 - Unidirectional TSP
摘要:写的麻烦了,修改了好久,用递归写的思路不是很好,以后要优化一下,用递推再做一遍。代码是下:#include<stdio.h>#include<string.h>#define INF 0x7fffffffint a[15][110], py[110][110][110],ans[110][110];int m, n;int dp(int p, int q, int x){ if(ans[p][q] != 16843009) return ans[p][q]; if(q == n) return a[p][q]; else if(p>=1&&p<
阅读全文
posted @
2012-03-13 00:00
BFP
阅读(264)
推荐(0)
UVA 10003 - Cutting Sticks
摘要:最优矩阵链乘问题:状态转移方程如下:(比较繁琐,稍后会有优化版)f[i][j] = f[i][k] + f[k][j] + a[j] - [i];//a[]存储切点i,j代表线段的头和尾利用递推运算,先把线段之间没有切点的收费情况即f[i][j]赋值为零,然后利用这个推出线段之间只有一个切点的线段,如此不断扩大,当线段的头尾一个是0一个是给出的长度,也就AC了:代码如下:(此代码不理想,浪费空间,但可AC)#include<stdio.h>#include<string.h>#define INF 0x7fffffff#define MAXN 1000 + 10int
阅读全文
posted @
2012-03-10 22:32
BFP
阅读(577)
推荐(1)
UVA 647 Coin Change
摘要:这道题不是我做出来的:但是方法很值得学习,首先通过这种方法我才知道在线oj判题的时候不是一个数据一个数据的而是一个文件一组,也就是判断程序运行时间的输入不是一个数据而是一组数据,所以本题采用了打表法。因为用正常的思路复杂度接近O(n3),时间接近三秒,而用打表法只需运行一遍算出7489种状态,再输入时只需调用即可,时间为0.03s左右:代码如下:#include<stdio.h>#include<string.h>#define MAXN 8000int n;int V[5], f[MAXN];void prepare(){ int i, j; n = 7489; me
阅读全文
posted @
2012-03-10 10:40
BFP
阅读(259)
推荐(0)