题目描述
给一个环形的墙壁涂颜色,颜色一共有 k 种,墙壁被竖直地划分成 n 个部分,相邻的部分颜色不能相同。请你写程序计算出一共有多少种给墙壁上色的方案?
例如,当 n=5,k=3时,下面是一种合法的涂色方案
而由于墙壁是环形的,所以下面就是一种非法的方案
输入
输入两个数字 n,k(1≤n≤103,2≤k≤10)分别代表墙壁数量和颜色种类。
输出
对于每个询问,输出一行整数,合法的墙壁涂色方案数。
样例输入1
5 3
样例输出1
30
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX_N 1000
#define MAX_K 10
class BigInt : public vector<int> {
public:
BigInt() { push_back(0);}
BigInt(int x) {
push_back(x);
process_digit();
}
BigInt& operator+=(const BigInt& a) {
for (int i = 0; i < a.size(); i++) {
if (i < size()) at(i) += a[i];
else push_back(a[i]);
}
process_digit();
return *this;
}
private:
void process_digit() {
for (int i = 0; i < size(); i++) {
if (at(i) < 100000) continue;
if (i + 1 == size()) push_back(0);
at(i + 1) += at(i) / 100000;
at(i) %= 100000;
}
return;
}
};
ostream& operator<<(ostream& out, const BigInt &a) {
out << a[a.size() - 1];
for (int i = int(a.size()) - 2; i >= 0; i--) {
/*for (int j = 10000; j > 0; j /= 10) {
out << a[i] % (j * 10) / j;
}*/
printf("%05d", a[i]);
}
return out;
}
BigInt f[2][MAX_K + 5][MAX_K + 5];
int main() {
int n, k;
cin >> n >> k;
//f[ws][i][j]代表ws块墙壁,第一块墙壁染第i种颜色,最后一块墙壁染第j种颜色的方法总数
for (int i = 1; i <= k; i++) f[1][i][i] = 1;
for (int ws = 2; ws <= n; ws++) {
for (int i = 1; i <= k; i++) {
for (int j = 1; j <= k; j++) {
f[ws % 2][i][j] = 0;
for (int l = 1; l <= k; l++) {
if (l == j) continue;
f[ws % 2][i][j] += f[(ws - 1) % 2][i][l];
}
}
}
}
BigInt ans = 0;
for (int i = 1; i <= k; i++) {
for (int j = 1; j <= k; j++) {
if (i == j) continue;
ans += f[n % 2][i][j];
}
}
cout << ans << endl;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
class BigInt : public vector<int> {
public:
BigInt() { push_back(0); }
BigInt(int x) {
push_back(x);
process_digit();
}
BigInt operator*=(int x) {
for (int i = 0; i < size(); i++) {
at(i) *= x;
}
process_digit();
return *this;
}
BigInt operator*(int x) {
BigInt ret(*this);
ret *= x;
return ret;
}
BigInt operator+=(BigInt a) {
for (int i = 0; i < a.size(); i++) {
if (i == size()) push_back(a[i]);
else at(i) += a[i];
}
process_digit();
return *this;
}
BigInt operator+(BigInt a) {
BigInt ret(*this);
ret += a;
return ret;
}
private:
void process_digit() {
for (int i = 0; i < size(); i++) {
if (at(i) < 10) continue;
if (i + 1 == size()) push_back(0);
at(i + 1) += at(i) / 10;
at(i) %= 10;
}
return;
}
};
ostream& operator<<(ostream& out, BigInt a) {
for (int i = a.size() - 1; i >= 0; i--) {
out << a[i];
}
return out;
}
BigInt f[1005];
int main() {
int n, k;
cin >> n >> k;
f[1] = k;
f[2] = f[1] * (k - 1);
f[3] = f[2] * (k - 2);
for (int i = 4; i <= n; i++) {
f[i] = f[i - 1] * (k - 2) + f[i - 2] * (k - 1);
}
cout << f[n];
return 0;
}