2012年4月23日
摘要: 这道题以二叉搜索树为背景,有点像最优矩阵链乘的问题:设f[i][j] 表示元素i到元素j的最优解,设k为i到j元素所形成二叉树的根,则有f[i][j] = min{f[i][k-1]+f[k+1][j]+sum[i][j]-a[k]},这里sum[i][j]为i到j的查找频率之和,a[k]为root的查找频率,因此我们要求所有元素的前缀和,为什么要加sum[i][j]-a[k];因为我们每加一层,相当于加了sum[i][j]-a[k];代码如下;#include<stdio.h>#include<string.h>#define MAXN 260#define INF 阅读全文
posted @ 2012-04-23 14:29 BFP 阅读(384) 评论(0) 推荐(0) 编辑
  2012年4月18日
摘要: 由于添加字母和删除字母的效果是一样的,因此我们这里就只进行删除和替换操作。用f【i】【j】表示将第i到j之间的字串变成回文串的最小操作步数,然后转移方程为当s【i】!=s【j】时,f【i】【j】 = min( f【i+1】【j】 ,f【i】【j-1】,f【i+1】【j-1】)+1;当相等时f【i】【j】 =f【i+1】【j-1】;递归操作更方便;#include<stdio.h>#include<string.h>#define MAXN 1010#define INF 0x7fffffffchar s[MAXN];int n, f[MAXN][MAXN];int dp 阅读全文
posted @ 2012-04-18 22:16 BFP 阅读(217) 评论(0) 推荐(0) 编辑
摘要: 这道题考察的是这样的一个问题,在m行的第一列中找一些数,计算它们之和的平方,然后再计算对应的第二列中的那些数的和的平方,这两个数之和为s2就可以了。这里我借鉴了二维费用的背包问题,易于理解,速度还可以。代码如下:#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXN 45int n, m, s;int a[MAXN][2], f[310][310], x[310], y[310];void solve(){ int p = 0; int min = 0x7fffffff; for(i 阅读全文
posted @ 2012-04-18 15:48 BFP 阅读(317) 评论(0) 推荐(0) 编辑
  2012年4月11日
摘要: 第一次把题意理解错了,第二次因为一个 ] ,wrong了四次,还好在极值样例的检测下,找出来了。以后打代码一定要注意了。我是这样定义状态的,f[i][j]表示在第i天时,在城市j所花费的最小费用,很简单的dp题:代码如下:#include<stdio.h>#include<string.h>#define INF 2000000000long long b[15][15][35];long long f[1010][15];int n, k, num;void output(){ if(f[k+1][n] < INF)printf("The best f 阅读全文
posted @ 2012-04-11 16:55 BFP 阅读(396) 评论(0) 推荐(0) 编辑
  2012年4月10日
摘要: 动规题,方法很巧。很像背包问题,这道题我们可以想成给了空间M,让你求价值之和与M的差最小的那个和,如果超过了M的某个和与小于M的某个和与M之差相等,取小的那个,而我们的方法是将背包空间扩充两倍,初始化f[0][0] = 1;f[i][0] = 0;我们利用01背包的知识求出2M空间的所有值,然后从f[N][j]中以M为中心向两边找,找到第一个为1的f[N][j](如果两边相等取小的),即为所求。(从整个空间开始不断的减少(增加)空间,看最近的哪一个恰好能够装满)。代码如下:#include<stdio.h>#define MAXN 2010int f[MAXN][MAXN], A[ 阅读全文
posted @ 2012-04-10 00:45 BFP 阅读(317) 评论(0) 推荐(0) 编辑
  2012年4月6日
摘要: 这道题是模仿别人的bfs,却也有所收获。把12个棋位的有无棋子整体看作一个状态,然后宽搜就可以了。代码如下:#include<stdio.h>#include<string.h>#define MAXN 11000char b[20];int q[MAXN], hash[MAXN], d[MAXN];int N, n;void solve(){ int x,i; int front = 0, rear = 0; memset(hash,0,sizeof(hash)); hash[q[rear]] = 1; d[rear] = 0; rear ++; w... 阅读全文
posted @ 2012-04-06 20:50 BFP 阅读(312) 评论(0) 推荐(0) 编辑
  2012年4月5日
摘要: 典型的bfs。代码如下:#define MAXN 55#define INF 0x7fffffff#include<stdio.h>#include<string.h>int T, N, M, Sr,Sc,Er,Ec, min;char s[MAXN][MAXN], vis[MAXN][MAXN];int q[MAXN*MAXN], dis[MAXN][MAXN];int dx[4] = {0,0,-1,1};int dy[4] = {1,-1,0,0};void solve(int x, int y){ min = INF; memset(vis,0,sizeof(v 阅读全文
posted @ 2012-04-05 23:35 BFP 阅读(223) 评论(0) 推荐(0) 编辑
  2012年3月31日
摘要: 这道题的意思是让我们求一个上升子序列 + 一个下降字序列,且两边的长度是相等的,由于用正常的 O(n2) 算法会 TLE ,所以这里我们采用二分法求最长上升子序列,这里需要利用两个栈来储存“相当于”最长上升子序列的串(我利用一个栈通过再次初始化栈顶top来第二次使用),在此同时开两个数组f1[i],f2[i],分别表示前i个元素的最长字串长度,最后比较同一个位置时(注意f1,f2一个正一个反)两个数组值的大小,取小的一个(因为要求两边长度相等)赋值给新开的数组flag[](我用num不断刷新),最后遍历数组,找出其最大的就可以了。这里说一下二分法求最长上升子序列:复杂度为O(n×lo 阅读全文
posted @ 2012-03-31 22:35 BFP 阅读(779) 评论(0) 推荐(1) 编辑
  2012年3月30日
摘要: sort+二分(求上下界):qsort + 纯二分 会TE:sort用法:头文件:#include <algorithm>using namespace std;1.默认的sort函数是按升序排。对应于1)sort(a,a+n); //两个参数分别为待排序数组的首地址和尾地址2.可以自己写一个cmp函数,按特定意图进行排序。对应于2)例如:int cmp( const int &a, const int &b ){ if( a > b ) return 1; else return 0;}sort(a,a+n,cmp);是对数组a降序排序又如:int cmp( 阅读全文
posted @ 2012-03-30 22:31 BFP 阅读(177) 评论(0) 推荐(1) 编辑
  2012年3月29日
摘要: 终于弄出来了,不会做的都是难题,会做的都是水题啊,水啊。这道题的大意是:从母串里找出有多少个子串为给出的字串,分两步思考:一 是先把状态方程写出来,由题分析我们可以这样设状态: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 阅读(647) 评论(0) 推荐(1) 编辑