程序设计思维与实践 Week14 作业

D - Q老师染砖

Description
衣食无忧的 Q老师 有一天突发奇想,想要去感受一下劳动人民的艰苦生活。

具体工作是这样的,有 N 块砖排成一排染色,每一块砖需要涂上红、蓝、绿、黄这 4 种颜色中的其中 1 种。且当这 N 块砖中红色和绿色的块数均为偶数时,染色效果最佳。

为了使工作效率更高,Q老师 想要知道一共有多少种方案可以使染色效果最佳,你能帮帮他吗?

Input
第一行为 T,代表数据组数。(1 ≤ T ≤ 100)

接下来 T 行每行包括一个数字 N,代表有 N 块砖。(1 ≤ N ≤ 1e9)

Output
输出满足条件的方案数,答案模 10007。

Sample Input
2
1
2
Sample Output
2
6


思路:

  • 首先显然是个DP,第i个砖可以有i-1个砖推过来,A[i]代表到i块转红绿均为偶,B[i]奇奇,C[i]奇偶
  • A[i]=2 * A[i-1]+C[i-1]
  • B[i]=2 * B[i-1]+C [i-1]
  • C[i]=2 * A[i-1]+2 * B[i-1]+2 * C[i-1]
  • n太大了,普通做法是不行的
  • 可以看到当前状态可以有上一个形式一样的状态得到,那么可以用矩阵

#include <iostream>
using namespace std;

const int N = 3;
struct Matrix
{
	int x[N][N];
	Matrix() { memset(x, 0, sizeof(x)); }
	Matrix(const Matrix& t) { memcpy(x, t.x, sizeof(x)); }

	Matrix operator*(const Matrix& rhs)
	{
		Matrix ret;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
			{
				ret.x[i][j] = 0;
				for (int k = 0; k < N; k++)
					ret.x[i][j] += x[i][k] * rhs.x[k][j] % 1007;
				ret.x[i][j] %= 1007;
			}
		return ret;
	}
};

Matrix quick_pow(Matrix a, int x)
{
	Matrix ret;
	for (int i = 0; i < N; i++)
		ret.x[i][i] = 1;
	while (x)
	{
		if (x & 1) ret = ret * a;
		a = a * a;
		x >>= 1;
	}
	return ret;
}
int main()
{
	int T; cin >> T;
	
	Matrix r;
	r.x[0][0] = 2;
	r.x[0][1] = 0;
	r.x[0][2] = 1;

	r.x[1][0] = 0;
	r.x[1][1] = 2;
	r.x[1][2] = 1; 

	r.x[2][0] = 2;
	r.x[2][1] = 2;
	r.x[2][2] = 2;
	while (T--)
	{
		int n; cin >> n;
		if (n == 1)
		{
			cout << 2 << endl;
			continue;
		}
		int A = 2, B = 0, C = 2;
		Matrix m = quick_pow(r, n - 1);
		int* tmp = m.x[0];
		int ans = tmp[0] * A + tmp[1] * B + tmp[2] * C;
		cout << ans % 10007 << endl;
	}
}

E - Q老师度假

Description
忙碌了一个学期的 Q老师 决定奖励自己 N 天假期。

假期中不同的穿衣方式会有不同的快乐值。

已知 Q老师 一共有 M 件衬衫,且如果昨天穿的是衬衫 A,今天穿的是衬衫 B,则 Q老师 今天可以获得 f[A][B] 快乐值。

在 N 天假期结束后,Q老师 最多可以获得多少快乐值?

Input
输入文件包含多组测试样例,每组测试样例格式描述如下:

第一行给出两个整数 N M,分别代表假期长度与 Q老师 的衬衫总数。(2 ≤ N ≤ 100000, 1 ≤ M ≤ 100)

接下来 M 行,每行给出 M 个整数,其中第 i 行的第 j 个整数,表示 f[i][j]。(1 ≤ f[i][j] ≤ 1000000)

测试样例组数不会超过 10。

Output
每组测试样例输出一行,表示 Q老师 可以获得的最大快乐值。

Sample Input
3 2
0 1
1 0
4 3
1 2 3
1 2 3
1 2 3
Sample Output
2
9


思路:


#include <iostream>
using namespace std;

const int N = 3;
struct Matrix
{
	int x[N][N];
	Matrix() { memset(x, 0, sizeof(x)); }
	Matrix(const Matrix& t) { memcpy(x, t.x, sizeof(x)); }

	Matrix operator*(const Matrix& rhs)
	{
		Matrix ret;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
			{
				ret.x[i][j] = 0;
				for (int k = 0; k < N; k++)
					ret.x[i][j] += x[i][k] * rhs.x[k][j] % 1007;
				ret.x[i][j] %= 1007;
			}
		return ret;
	}
};

Matrix quick_pow(Matrix a, int x)
{
	Matrix ret;
	for (int i = 0; i < N; i++)
		ret.x[i][i] = 1;
	while (x)
	{
		if (x & 1) ret = ret * a;
		a = a * a;
		x >>= 1;
	}
	return ret;
}
int main()
{
	int T; cin >> T;
	
	Matrix r;
	r.x[0][0] = 2;
	r.x[0][1] = 0;
	r.x[0][2] = 1;

	r.x[1][0] = 0;
	r.x[1][1] = 2;
	r.x[1][2] = 1; 

	r.x[2][0] = 2;
	r.x[2][1] = 2;
	r.x[2][2] = 2;
	while (T--)
	{
		int n; cin >> n;
		if (n == 1)
		{
			cout << 2 << endl;
			continue;
		}
		int A = 2, B = 0, C = 2;
		Matrix m = quick_pow(r, n - 1);
		int* tmp = m.x[0];
		int ans = tmp[0] * A + tmp[1] * B + tmp[2] * C;
		cout << ans % 10007 << endl;
	}
}
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读