今日回顾_算法专题_2020年12月18日
一、NEMU PART
今天开始做nemu实验了,首先是对代码进行总体的回顾与整理,搞清楚在哪里写代码,同时在github上找到了代码源可用作参考。
1、完成部分:
(1)重新学习了cache(高速缓存)以及它的用途与用法:
cache是为了适配CPU超快的速度而诞生的产物,它为CPU提供了缓冲的余地。
a、工作原理:
将CPU近期用到的文件放进高速缓存里面,下此CPU再访问内存的时候检查cache内是否有目标文件,如果有就直接调出来用,由于cache比较小,同时速度也比内存快得多,由此可以节省I/O时间,提高效率。
在一级缓存的基础上,人们衍生出二级缓存,用于匹配一级缓存的速度,在nemu中的一级缓存,二级缓存都做了简化(详情可见PA3指导):
b、 主要获得:
1、地址计算:
nemu中:标记位、tag位、信息位。
详情看收藏夹。
2、脏位理解:
脏位是一个类似标记为作用的标记位,标记着这个信息是否更改过,如果这个标记位为false表示没更改过,如果是true表示更改过,需要与内存进行同步。
二、算法部分
1、学习部分:
(1)最优子结构性质,见第一篇博客;
(2)解空间树,状态树;
问题:
物品数量:4;
背包容量:5;
物品:(2,3),(1,2),(3,4),(2,2)
(3)递归调用树:
重复是指,同一层,同时重量相同的节点及其子节点都是重复操作。
(4)递归调用优化代码:
利用数组存储数据,将已经计算过的放进数组内,这样下此取的时候就可以节省时间:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
//问题2c
int n = 4;
int w1 = 5;
int w[4] = {2,1,3,2};
int v[4] = {3,2,4,2};
int dp[4][6];
int res( int i , int j ){
int rec = 0;
if ( i == n ){
rec = 0;
}
else if ( j < w[i] ){
rec = res( i+1 , j );
}
else{
rec = max ( res( i+1 , j ) , res( i+1 , j - w[i] ) + v[i] );
}
return rec;
}
int get_data( int i , int j ){
if ( dp[i][j] == -1 ){
dp[i][j] = res( i , j );
}
return dp[i][j];
}
int main(){
memset( dp , -1 , sizeof(dp) );
cout << get_data( 0 , w1 ) << endl;
}
(5)动态规划代码及其优化:
动态规划0/1背包问题,递归式:
动态规划代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n = 4;
int w1 = 5;
int w[4] = {2,1,3,2};
int v[4] = {3,2,4,2};
int dp[5][6];
void dp_solve( );
int main(){
for ( int i = 0 ; i <= 5 ; i++ ){
dp[0][i] = 0;
}
dp_solve();
cout << dp[4][5] <<endl;
}
void dp_solve(){
for( int i = 0 ; i <= n ; i++ ){
for ( int j = 0 ; j <= 5 ; j++ ){
if ( j >= w[i] ){
dp[i+1][j] = max( dp[i][j] , dp[i][j-w[i]]+v[i] );
}
else{
dp[i+1][j] = dp[i][j];
}
}
}
}
空间优化:利用0/1背包特点进行优化,可以利用一维数组来缩减空间大小,详情见收藏夹:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n = 4;
int w1 = 5;
int w[4] = {2,1,3,2};
int v[4] = {3,2,4,2};
int dp[6] = {0};
void save_solve();
int main(){
save_solve();
cout << dp[5] <<endl;
}
void save_solve(){
for ( int i = 0 ; i < n ; i++ ){
for ( int j = 5 ; j >= w[i] ; j-- ){
dp[j] = max( dp[j] , dp[j-w[i]]+v[i] );
}
}
}
写博客的第一天: