二维滚动数组
例子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
进制转换可以看看这个
具体代码如下
#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 行的结果 ,只用两个一维数组,滚动使用)如
有动态表的背包问题可以去这看看
#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)(n ≥ 2,n ∈ 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;
}
个人看法,如有错误,请指出
如有侵权,请联系删除