答题卡是n * n 的,要求出所有的使横竖答题卡对称的涂写方案。
首先,应该看清楚题面给出的条件,横竖答题卡都只能填一个答案,并且横竖答题卡是要对称的。所以横答题卡某一行的答案确定之后,对应的竖答题卡的某一列的答案也就确定了,并且交于这两个答案的行和列也已经确定了
以n = 3
可以看到,当将第一行的答案放在第一列的时候,剩下的就是求的答题卡规模为(n - 1) * (n - 1) 的所有方案,当第一行的答案放在第二列的时候,剩下的就是求答题卡规模为(n - 2) * (n - 2) 的所有方案(因为此时根据答案横竖相同要求的对称性,确定了一行的同时也就确定了一列,所以此时有两行和两列都不能进行选择),同理将第一行的答案放在第三列也是一样的。而n = 4
的所有情况也是跟n = 3
类似。
所以我们可以得出这样的结论:
在棋盘规模为 的情况下,除去将第一行的答案放在第一列之外(这种情况是转化为求(n - 1) * (n - 1)
的所有方案数),剩余的情况有(n - 1)
种,并且这(n - 1)种
情况都是一样的,都是求棋盘规模为(n - 2) * (n - 2)
的所有方案数。
F(n) = F(n - 1) + (n - 1) * F(n - 2)
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000000 + 7;
int main() {
int n;
cin >> n;
//res[i]表示i * i的矩阵的方案数目
vector<long long> res;
res.emplace_back(1), res.emplace_back(1), res.emplace_back(2);
for(int i = 3; i <= n; i++) {
res.emplace_back((res[i - 1] + (((i - 1) % MOD) * (res[i - 2] % MOD))%MOD) % MOD);
}
cout << res[n] << endl;
return 0;
}
比较经典的多重背包问题
#include <iostream>
using namespace std;
int dp[3][210];
int money[3] = {1, 2, 5};
int main() {
int n;
cin>>n;
for(int i = 0; i <= 200; i++)
dp[0][i] = 1;
dp[1][0] = 1, dp[2][0] = 1;
for(int i = 1; i < 3; i++) {
for(int j = 0; j <= 200 ; j++)
if(j >= money[i])
dp[i][j] = dp[i-1][j] + dp[i][j-money[i]];
else
dp[i][j] = dp[i-1][j];
}
cout<<dp[2][n] <<endl;
return 0;
}
利用斐波那契数列的通项公式进行推导,最后得到的结果为(-1)^n。所以只需要判断一下n的奇偶性即可得到答案。
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
if(s[s.size() - 1] % 2 == 0)
cout << 1 << endl;
else
cout << -1 << endl;
return 0;
}