2015_3_21_greedy_algo

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;	//通过下标去修改其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;
}


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值