小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oo***oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
一个整数,表示最小操作步数。
o****o****
*o***o**o***
#include <iostream>
#include <cstring>
using namespace std;
int step;
int n,m;
char szBuf[1000] = " ";
char reszBuf[1000] = " ";
//* 表示正面,用 o 表示反面(是小写字母,不是零) '*'-1 'o'-0
bool check(int *p, int *rep)
{
for(int i = 0; i < n; i++)
{
if(p[i] != rep[i])
{
return false;
}
}
return true;
}
void change(int *p, const int *rep)
{
for(int i = 0; i < n-1; i++)
{
if(p[i] != rep[i])
{
p[i] = !p[i];
p[i+1] = !p[i+1];
step++;
}
}
}
int main()
{
cin >> szBuf >> reszBuf;
n = strlen(szBuf);
m = strlen(reszBuf);
int a[n] = {0};
int b[m] = {0};
for(int i = 0; i < n; i++)
{
if('*' == szBuf[i])
{
a[i] = 1;
}
else if('o' == szBuf[i])
{
a[i] = 0;
}
}
for(int i = 0; i < m; i++)
{
if('*' == reszBuf[i])
{
b[i] = 1;
}
else if('o' == reszBuf[i])
{
b[i] = 0;
}
}
while(true)
{
if(check(a,b))
{
break;
}
change(a,b);
}
cout << step << endl;
return 0;
}
用贪心算法解背包问题的基本步骤:
首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直地进行下去,直到背包装满为止。
问题二、 哈夫曼编码
哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。其压缩率通常在20%~90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。
给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。
| a | b | c | d | e | f |
频率(千次) | 45 | 13 | 12 | 16 | 9 | 5 |
定长码 | 000 | 001 | 010 | 011 | 100 | 101 |
变长码 | 0 | 101 | 100 | 111 | 1101 | 1100 |
问题三、单源最大路径
给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。
1、算法基本思想
Dijkstra算法是解单源最短路径问题的贪心算法。
其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。
初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。
Dijkstra算法的迭代过程:
迭代 | s | u | dist[2] | dist[3] | dist[4] | dist[5] |
初始 | {1} | - | 10 | maxint | 30 | 100 |
1 | {1,2} | 2 | 10 | 60 | 30 | 100 |
2 | {1,2,4} | 4 | 10 | 50 | 30 | 90 |
3 | {1,2,4,3} | 3 | 10 | 50 | 30 | 60 |
4 | {1,2,4,3,5} | 5 | 10 | 50 | 30 | 60 |