您的位置:首页 > 编程语言 > Go语言

2015_3_21_greedy_algo

2015-03-21 16:16 134 查看
1000. Fibonacci 1

Total: 471
Accepted: 317

   

Time Limit: 1sec    Memory Limit:256MB

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + Fn-2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

 

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

 

Given an integer n, your goal is to compute the last Fn mod (10^9 + 7).

Input

 The input test file will contain a single line containing n (n ≤ 100).

There are multiple test cases!

Output

 For each test case, print the Fn mod (10^9 + 7).

Sample Input

 Copy sample input to clipboard

9

Sample Output

34

普通的递归搞定

#include <cstdio>
#include <cmath>
using namespace std;

double fib(int n){
if (n == 0 || n == 1)
return n;
else
return fib(n-1) + fib(n-2);
}

const int m = pow(10, 9) + 7;

int main(){
int n;
while (scanf("%d", &n) != EOF){
printf("%ld\n", (long long)fib(n) % m);
}
return 0;
}


1001. Fibonacci 2

Total: 1007
Accepted: 231

   

Time Limit: 1sec    Memory Limit:256MB

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + Fn-2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

 

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

 

Given an integer n, your goal is to compute the last Fn mod (10^9 + 7).

Input

The input test file will contain a single line containing n (n ≤ 2^31-1).

There are multiple test cases!

Output

 For each test case, print the Fn mod (10^9 + 7).

Sample Input

 Copy sample input to clipboard

9

Sample Output

34

Hint

 You may need to use "long long".

这题用例巨大,显然不能再用递归。学习了一种新思路,模拟矩阵的乘法后利用矩阵快速幂求解





#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 2;
const int mod = pow(10, 9) + 7;
int n = 2;	//矩阵大小
int num;	//幂大小

struct mat
{
long long arr[maxn][maxn];
mat(){
memset(arr, 0, sizeof(arr));
}
};

mat mul(mat a, mat b){
mat ans;
for(int i = 0; i < n; i++){			//代表左矩阵的行数
for(int k = 0; k < n; k++){		//代表右矩阵行数
if(a.arr[i][k]){
for(int j = 0; j < n; j++){
ans.arr[i][j] += a.arr[i][k] * b.arr[k][j];
if(ans.arr[i][j] >= mod)
ans.arr[i][j] = ans.arr[i][j] % mod;
}
}
}
}
return ans;
}

mat power(mat p,int k)
{
if(k == 1)
return p;

mat e;
for(int i = 0; i < n; i++)
e.arr[i][i] = 1;		//初始化为[1, 0; 0, 1]
if(k == 0)
return e;				//0次幂 就是e
while(k){
if(k & 1)				//直到k
e = mul(e,p);
p = mul(p,p);
k >>= 1;
}
return e;
}

int main(){
mat ori;					//题目中的原始矩阵[1, 1; 1, 0]
ori.arr[0][0] = ori.arr[0][1] = ori.arr[1][0] = 1;
while(scanf("%d", &num) != EOF){
mat ans;
ans = power(ori,num);
printf("%ld\n", ans.arr[0][1]);
}
return 0;
}


1002. Huffman coding

Total: 561
Accepted: 152

   

Time Limit: 1sec    Memory Limit:256MB

Description

In computer science and information theory, a Huffman code is an optimal prefix code algorithm.

In this exercise, please use Huffman coding to encode a given data.

You should output the number of bits, denoted as B(T), to encode the data:

B(T)=∑f(c)dT(c),

where f(c) is the frequency of character c, and dT(c) is be the depth of character c's leaf in the tree T.

 

Input

The first line is the number of characters n.

The following n lines, each line gives the character c and its frequency f(c).

Output

 Output a single number B(T).

Sample Input

 Copy sample input to clipboard

5

0 5

1 4

2 6

3 2

4 3

Sample Output

45

Hint

0: 01

1: 00

2: 11

3: 100

4: 101

霍夫曼编码就是用尽可能短的码编出一长串数据,具体算法:
1.将各数据出现的频率放入优先队列(用最小堆实现),然后每次从堆中取出两个元素L, R,作为树中某节点的左右孩子。
2.将L+R之和丢回优先队列中,一直重复做直到堆中仅剩一个元素
3.根据树的层数,叶子节点代表一个编码对象,根为0,向下求出叶子结点层数之和

/*
5
0 2
1 5
2 6
3 8
4 10
*/
#include <queue>
#include <vector>
#include <cstdio>
using namespace std;

struct node{
int freq;			//记录频率
int parent;			//记录parent的数组下标
int pos;			//记录本频率对应字符存储的位置
bool leaf;			//是否叶子节点
node(int f = -1, int pos = -1, bool lf = true){
freq = f;
this->pos = pos;
parent = -1;
leaf = lf;
}
};

typedef struct{
bool operator()(node x, node y){
return x.freq > y.freq;
}
}cmp;

node arr[2010];
int index = 0;
int main(){
priority_queue<node, vector<node>, cmp> q;
int n, freq;
char ch;
scanf("%d", &n);
getchar();
for (int i = 0; i < n; i++){		//store freq in priority queue(little root heap)
scanf("%c%d", &ch, &freq);		//一开始没用字符%c 导致 WA
getchar();
node temp(freq);
q.push(temp);
}
while(q.size() > 1){
int left_pos = 0, right_pos = 0;
if (q.top().leaf == true){
arr[index] = q.top();	//the smallest as left child
left_pos = index++;
}
else
left_pos = q.top().pos;	//若已经存在,则把已存在结点的字符对应下标拿出来
int Lfreq = q.top().freq;
q.pop();

if (q.top().leaf == true){
arr[index] = q.top();	//the second smallest as right child
right_pos = index++;
}
else
right_pos = q.top().pos;
int Rfreq = q.top().freq;
q.pop();

int sum = Lfreq + Rfreq;	//their sum becomes parent
node P(sum, index, false);
arr[left_pos].parent = arr[right_pos].parent = index
4000
;	//通过下标去修改其parent

arr[index++] = P;
q.push(P);				//sum back into the priority_queue
}
arr[index] = q.top();
arr[index].pos = index;		//记住把根节点的情况补全

int result = 0;
for (int i = 0; i <= index; i++){
if (arr[i].leaf == true){
int lv = 0;
int ptr = arr[i].parent;
while (ptr > 0){
lv++;
ptr = arr[ptr].parent;
}
result += (lv * arr[i].freq);
}
}

printf("%d\n", result);
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: