一维滚动数组与二维滚动数组(例子翻倍数组,背包问题,斐波那契数列)

二维滚动数组

例子1翻倍数组(即把数字翻倍)如

创建一个两行4列的二维数组A[2][4],将

   1,2,3,3                     放到A数组的第一行,翻倍后(1,4,9,9   )

   1,4,9,9                     放到A数组的第二行,翻倍后(1,16,81,81)

   1,16,81,81               放到A数组的第一行,翻倍后(1,256,6561,6561)

   1,256,6561,6561     放到A数组的第二行,翻倍后(1, 65536 ,43046721, 43046721)

   1, 65536 ,43046721,43046721 放到A数组的第一行

    最后输出   1, 65536 ,43046721, 43046721

&运算符(代码要用到的),具体规则两个二进制数中对应位置只要有一个0,那么结果位置就为0(1对1就为1),如

(十进制)1&1->(二进制)01&01->(二进制)01->(十进制)1

(十进制)0&1->(二进制)00&01->(二进制)00>(十进制)0

进制转换可以看看这个

https://blog.csdn.net/heroisppp/article/details/123097809?spm=1001.2014.3001.5502https://blog.csdn.net/heroisppp/article/details/123097809?spm=1001.2014.3001.5502

具体代码如下

#include<iostream>
using namespace std;
#define  MAX 4
int  main()
{
	int A[2][MAX] = { 1,2,3,3 };
	int b(4);
	//滚动数组,重点&运算符
	for (int i = 1; i <=b; i++)
	{   
		for (int j = 0; j < MAX; j++)
		{
			A[i&1][j] = A[i -1& 1][j] * A[i -1& 1][j]; //i=1,A[1][j]=A[0][j] * A[0][j];	
		}
	}
	/// 判断结果是在滚动数组的哪一行
	if (b & 1)
	{
			for (int i = 0; i < MAX; i++)
			{
				cout << A[1][i] << " ";
			}
			cout << endl;
	}
	else
	{
		for (int i = 0; i < MAX; i++)
			{
				cout << A[0][i] << " ";
			}
		cout << endl;
	}
	return 0;
}

翻倍数组另外写法(不用&运算符)

#include<iostream>
using namespace std;
#define  MAX 4
int  main()
{
	int A[2][MAX] = { 1,2,3,3 };
	int a(0);
	int b(4);
	while (b)
	{
		if (!(a % 2))
		{
			for (int i = 0; i < MAX; i++)
			{
				A[1][i] = A[0][i] * A[0][i];
			}
			a++;
		}
		else
		{
			for (int i = 0; i < MAX; i++)
			{
				A[0][i] = A[1][i] * A[1][i];
			}
			a++;
		}
		b--;
	}
	for (int j = 0; j < 2; j++)
	{
		for (int i = 0; i < MAX; i++)
		{
			cout << A[j][i] << " ";
		}
		cout << endl;
	}
	return 0;
}

例子2背包问题(计算第 i 行值时,只用到第 i - 1 行的结果 ,只用两个一维数组,滚动使用)

有动态表的背包问题可以去这看看

【动态规划】01背包问题(通俗易懂,超基础讲解)_Yngz_Miao的博客-CSDN博客_动态规划 背包问题问题描述有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?为方便讲解和理解,下面讲述的例子均先用具体的数字代入,即:eg:number=4,capacity=8i(物品编号)1234w(体积)2345v(价值)3456总...https://blog.csdn.net/qq_38410730/article/details/81667885?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165789917216782246430534%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165789917216782246430534&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-81667885-null-null.142%5Ev32%5Epc_rank_34,185%5Ev2%5Econtrol&utm_term=01%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98&spm=1018.2226.3001.4187

#include<iostream>
#include <algorithm>
using namespace std;
#define MAX 10010
int dp[2][MAX];
int wei[300];
int val[300];
int main()
{
	int C, n;
	cin >> n >> C;//物品个数,背包容量
	for (int s = 1; s <= n; s++)
	{
		cin >> wei[s] >> val[s];
	}
	for (int i = 1; i <= n; i++)
	{    /// 枚举前 i 件物品
		for (int j = 1; j <= C; j++)
		{   /// 枚举 1 ~ C 的任意容量
				
			if (j >= wei[i])   /// 若可以放进第 i 件物品时,取其大者
				dp[i & 1][j] = max(dp[i-1 & 1][j], dp[i - 1 & 1][j - wei[i]] + val[i]);//dp[1][1]=dp[0][1]
			else
			dp[i & 1][j] = dp[i - 1 & 1][j];  /// 不考虑第 i 件物品时
		}
	}
	/// 判断结果是在滚动数组的哪一行
	if (n & 1)
	{
		cout << dp[1][C] << endl; 
	}
	else
	{
		cout << dp[0][C] << endl; 
	}
	return 0;
}

输入 4 8
        2 3
        3 4
        4 5
        5 6

输出 10

一维滚动数组

例子1 背包问题
      在没有用滚动数组,保留动态表,在表中可以看出,第 i 行第j个状态只和第i-1行第j个状态与第i-1行第(j-wei[i])个状态有关。因此,只需要一个一维数组 dp[MAX]。注意,第二层循环要从后往前。max( dp[j], dp[j - wei[i]] + val[i] )中,其中dp[j] 表示的是只考虑前 i - 1 个物品(不放第i件物品),且背包容量是 j 时可以获得的最大值。

#include<iostream>
#include<iostream>
#include <algorithm>
using namespace std;
#define MAX 10000
int dp[MAX];
int wei[300];
int val[300];
int main()
{
	int C, n;
	cin >> n >> C;//物品个数,背包容量
	for (int s= 1; s <= n; s++)
	{
		cin >> wei[s] >> val[s];
	}
	for (int i = 1; i <= n; i++)
	{    /// 枚举前 i 件物品
		for (int j = C; j > 0; j--)
		{   /// 枚举 C到1 的任意容量
			if (j >= wei[i])   /// 若可以放进第 i 件物品时,取其大者
				dp[j] = max(dp[j], dp[j - wei[i]] + val[i]);
		}
	}
	if (C <= 10000)
		cout << dp[C] << endl;
	else
		cout << "你输入的背包容量超过" << endl;
	return 0;
}

输入 4 8
        2 3
        3 4
        4 5
        5 6

输出 10

例子2  斐波那契数列

 第几              1    2   3    4   5    6    7     8      9   

 数列              1、1、2、3、5、8、13、21、34、……

F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(≥ 2,∈ N*)

即选连续的三个数,前两个之和等于第三个(1、1、2->1+1=2,1、2、3、->1+2=3)

根据斐波那契数列的性质,写出输入在该数列的第几,输出对应的数列上的数(如输入1,输出1;输入8,输出21)

写法1

# include <iostream>
using namespace std;
int main()
{
	int n;
	int number[3];
	cin >> n;
	number[0] = 0;
	number[1] = 1;
		for (int i = 1; i <= n; i++)
		{
			number[2] = number[1] + number[0];
			number[1] = number[0];
			number[0] = number[2];
		}
	cout << number[2] << endl;
	return 0;
}

写法2

# include <iostream>
using namespace std;
int n;
int num[3];
int main()
{
	cin >> n;
	if (n >= 3)
	{
		num[0] = 1;
		num[1] = 1;
		for (int i = 3; i <= n; i++) 
		{
			num[2] = num[1] + num[0];
			num[1] = num[0];
			num[0] = num[2];
		}
		cout << num[2] << endl;
	}
	else cout << "1" << endl;
	return 0;
}

个人看法,如有错误,请指出

如有侵权,请联系删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroisppp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值