题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1080
LCS的变种:
状态转移:dp[i][j] = MAX(dp[i-1][j-1]+cost[a[i]][b[j]],dp[i-1][j]+cost[a[i]][SPACE],dp[i][j-1]+cost[SPACE][b[j]])
先将A-C-G-T各个匹配的代价打个表,DP时注意状态的初始化!
1 |
|
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1080
LCS的变种:
状态转移:dp[i][j] = MAX(dp[i-1][j-1]+cost[a[i]][b[j]],dp[i-1][j]+cost[a[i]][SPACE],dp[i][j-1]+cost[SPACE][b[j]])
先将A-C-G-T各个匹配的代价打个表,DP时注意状态的初始化!
1 | #include <stdio.h> |
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561
这道题意思是给你一棵树,必须先攻下父母节点后才能攻下其孩子节点。
以0为树根,然后对树种的节点做背包~
看了别人的报告后敲的代码,第一个树形DP的练习~囧
1 | #include <stdio.h> |
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3836
求至少需要添加多少条边,才能使这个图变成强连通图。
求强连通分支的算法:
STEP1:先DFS遍历图,记录DFS完成时间f[n]
STEP2:选择f[n]最大的(就是f[n]降序)再DFS反向图GT,得到各个强连通分量。
求出强分量后缩点处理得到分支图,对分支图的每个强连通分量统计出度和入度。只要在第二次DFS的过程中判断有没有访问其他已经找出的强连通分量(这边的证明过程在算法导论上P339有很详细的证明)。所以要把剩下的(还不能强连通的)几个强连通分量添加边形成整个强连通图,需要的边数就是:统计 入度=0 的顶点数 和 出度=0 的顶点数,选择两者中较大的一个,才能确保一个强连通图。
1 | #include <stdio.h> |
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3747
题目意思挺好理解的
不过 想了很久没想出来,最后看了大牛的代码才恍然大悟了,真觉得自己笨
1 | #include <stdio.h> |
这两天碰到最纠结的一题!无限WA了~~~
出发点是这样的:先统计出某个字母(我是对A)的总数进行统计sum,然后只要按照sum个单位长度在数组里进行查找(注意是一段一段),找出含有A的个数最多的那一段,然后在这段中剩下的B就是所要移动的最少次数了。
这题要用O(n)级的算法,否则TLE
用count[i]表示从开始到第i个位置含有A的数量(遍历一次数组完成)
然后可根据count[i]直接计算出任何一段含有A的数量
表示正常从i开始的(sum个长度)的一段
move_tmp = count[i+sum-1]-count[i-1];
(因为序列是循环的)下面时某一段的尾端重新跑到整个序列的头部的情况
move_tmp = count[(i+sum)%len-1]+count[len-1]-count[i-1];
1 | #include <stdio.h> |
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3818
给定一个菲波数序列,对它们进行合并,最后的结果要求是用最少的菲波数构成一个题目要求的数。
例如case1:
f(2)+f(2)+f(4) = f(3)+f(4) = f(5)
根据定义合并(判读两个数是否相邻的菲波数)
f(i) = f(i-1)+f(i-2) 如 f(5) = f(4)+f(3)
特殊情况当相同的两个菲波数时 form[i+1]==form[i]
例如有两个 f(a):第一个拆成f(a)=f(a-1)+f(a-2),另一个根据f(a)+f(a-1)=f(a+1)合并
所有有form[i+1]++,合并后的f(a+1) form[i]-=2 剩下的f(a-2)
1 | #include <stdio.h> |
题目分析:对N求折半查找的平均查找长度(ASL),数据结构都有学的。
1 | #include <stdio.h> |
秒杀题,不用说了,DFS求出@所在位置黑方块的最大连通区域
AC Code:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int W,H;
int sum;
char map[50][50];
int find[50][50];
typedef struct{ int x,y;} node;
int iPlus[4] = {-1,0,1,0};
int jPlus[4] = {0,-1,0,1};
void DFS(node p)
{
int k;
find[p.x][p.y] = 1;
node next;
sum++;
for ( k = 0; k < 4; k++)
{
next.x = p.x + iPlus[k];
next.y = p.y + jPlus[k];
if ( next.x >= 1 && next.x <= H && next.y >= 1 && next.y <= W)
{
if ( map[next.x][next.y]=='.' && !find[next.x][next.y] )
DFS(next);
}
}
}
int main()
{
freopen("Sample Input.txt","r",stdin);
system("Color F0");
int i,j,k;char ch;
node stand;
while ( scanf("%d%d",&W,&H),W&&H)
{
getchar();
for ( i = 1; i <= H; i++)
{
for ( j = 1; j <= W; j++)
{
scanf("%c",&ch);
if ( ch=='@') { stand.x = i; stand.y = j;}
map[i][j] = ch;
}
getchar();
}
sum = 0;
memset(find,0,sizeof(find));
DFS(stand);
printf("%d\n",sum);
}
getch();
return 0;
}
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3818
BFS水题,注意碰到敌人的时候要加上两个单位时间就可以了。(一直停留在使用循环队列的史前时代..)
1 | #include <stdio.h> |
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241
题目解释一下就是找出有多少块有石油的区域,就是数组中的@,这边相邻指的是是周围的八个位置。
算法就是使用DFS对区域进行标记,很水,不多说了。
1 | #include <stdio.h> |